首先必须需要有角色表,权限表,用户表
xml配置:
<bean id="MyRealm" class="cn.com.demo.shiro.ShiroPerssiom"></bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="MyRealm" />
</bean>
<bean id="shiroRole" class="cn.com.demo.shiro.ShiroFilter"></bean><!-- 自定义的filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" depends-on="shiroRole">
<property name="securityManager" ref="securityManager" />
<!-- 如果没有认证将要跳转的登陆地址,http可访问的url,如果不在表单认证过虑器FormAuthenticationFilter中指定此地址就为身份认证地址 -->
<property name="loginUrl" value="/login/login.html" />
<!-- 没有权限跳转的地址 -->
<property name="unauthorizedUrl" value="/user/main.html" />
<!-- 过滤定义,从上而下,蒋匿名的anon放最下面 -->
<property name="filterChainDefinitions">
<value>
<!-- 访问页面样式资源文件,不需要任何权限即可访问 -->
<!-- perms[search]表示访问此连接需要权限为search的用户
/developer=anon,roles[admin] perms[delete]
roles[admin]表示访问此连接需要用户的角色为admin-->
/test/demo.html=anon
/test/product.html=perms[add]
/user/**=roles[manage,admin] <!-- 任何一个都能登陆url,是因为实现了filter,详情请看下面类,如果没有些这个类用户只能有这两个角色才能登陆 -->
</value>
</property>
<property name="filters"><!-- 定义的filter引用 -->
<map>
<entry key="roles" value-ref="shiroRole"/>
</map>
</property>
</bean>
web.xml配置
<!-- Shiro配置 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
权限类
package cn.com.demo.shiro;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import cn.com.demo.entity.Perssion;
import cn.com.demo.entity.Role;
import cn.com.demo.entity.User;
import cn.com.demo.service.IPerssionService;
import cn.com.demo.service.IUserService;
public class ShiroPerssiom extends AuthorizingRealm
{
@Autowired
private IUserService userService;
@Autowired
private IPerssionService perssionService;
@Override
/*
* 授权认证
* */
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
{
//拿到用户名
String userName=(String) principalCollection.fromRealm(getName()).iterator().next();
User user=new User();
user.setUserUsername(userName);
//拿到用户名查询得到拥有的角色
List<User> list=userService.selectRole(user);
if(list.size()>0 && list != null){
// 权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo simple=new SimpleAuthorizationInfo();
Perssion perssion=null;
for(Role role:list.get(0).getSetRole()){
simple.addRole(role.getRoleName());
perssion=new Perssion();
perssion.setRoleId(role.getRoleId());
//通过角色拿到所有权限
Set<Perssion> listPer=perssionService.listPerssion(perssion);
if(listPer.size()>0 && listPer!=null){
for(Perssion per:listPer){
simple.addStringPermission(per.getPerssionName());
}
}
}
return simple;
}
return null;
}
@Override
/*
* 认证方式
* */
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException
{
//token中储存着输入的用户名和密码
UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
User user=new User();
System.out.println("验证当前Subject时获取到token为" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
user.setUserUsername(token.getUsername());
List<User> list=userService.selectRole(user);
if(list != null && list.size() > 0){
return new SimpleAuthenticationInfo(list.get(0).getUserUsername(), list.get(0).getUserPassword(), getName());
}
return null;
}
}
自定义登录和退出
package cn.com.demo.control;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import cn.com.demo.entity.Demo;
import cn.com.demo.entity.User;
import cn.com.demo.service.IDemoService;
import cn.com.demo.service.IUserService;
@Controller
@RequestMapping("/test")
public class DemoControl
{
@Autowired
private IDemoService demoService;
@Autowired
private IUserService userService;
/*
* 自定义登录
* */
@RequestMapping("/demo.html")
public String demoTest(User user,BindingResult bindingResult,RedirectAttributes redirectAttributes){
try
{
if (bindingResult.hasErrors())
{
return "/login";
}
List<User> list = userService.selectRole(user);
if (list != null && list.size() > 0)
{
//拿到令牌并将用户信息存入中
AuthenticationToken obj = new UsernamePasswordToken(user.getUserUsername(), user.getUserPassword());
SecurityUtils.getSubject().login(obj);
System.out.println(obj.toString());
return "demo";
}
}
catch (AuthenticationException e)
{
return "redirect:/user/main.html";
}
return "redirect:/user/main.html";
}
/*
* 退出
* */
@RequestMapping("/logout.html")
public void product(HttpServletResponse res){
try
{
SecurityUtils.getSubject().logout();
res.getWriter().print("tuichu");
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里继承了AuthorizationFilter用来 实现多个角色登录url
package cn.com.demo.shiro;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
public class ShiroFilter extends AuthorizationFilter
{
@Override
protected boolean isAccessAllowed(ServletRequest req, ServletResponse res, Object obj) throws Exception
{
Subject sub=getSubject(req, res);
String[] strs=(String[]) obj;
if(strs == null || strs.length==0){//没有角色限制,有权限访问
return true;
}
for(String str:strs){
if(sub.hasRole(str)){//若当前用户是rolesArray中的任何一个,则有权限访问
return true;
}
}
return false;
}
}