1、引入依赖
<!-- Spring 整合Shiro需要的依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
2、创建spring-shiro.xml配置文件
很多地方都注释掉了,感觉没什么用
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的UserRealm.java,这是要我们自己取实现的一个类 -->
<bean id="userRealm" class="com.qingqing.bpt.shiro.UserRealm"/>
<!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session -->
<!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 -->
<!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm"/>
</bean>
<!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 调用我们配置的权限管理器 -->
<property name="securityManager" ref="securityManager" />
<!-- 配置我们的登录请求地址-->
<!--<property name="loginUrl" value="/bpt/page/index.do" />-->
<!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->
<!--<property name="successUrl" value="/bpt/page/main.do" />-->
<!-- 如果您请求的资源不再您的权限范围,则跳转到退出地址 如果用了@requirePermission注解这里会失效!!!-->
<!--<property name="unauthorizedUrl" value="/login/noPermission.do" />-->
<property name="filterChainDefinitions">
<value>
<!--anon表示此地址不需要任何权限即可访问-->
/bootstrap/* = anon
/CSS/* = anon
/dist/* = anon
/js/* = anon
/images/* = anon
/tipso/* = anon
<!--roles[manager]表示访问此连接需要用户的角色为manager-->
<!--/user/add=roles[manager]-->
<!--perms[edit]表示访问此连接需要权限为edit的用户-->
<!--/role/edit/* = perms[edit]
/role/list = perms[view]-->
<!--/** = authc-->
</value>
</property>
</bean>
<!-- Shiro生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>
3、在你的spring-mvc配置文件配置里再加个配置
<!--shiro无权限访问资源时拦截,不知道为啥这里是无法拦截,没什么卵用,所以我用了异常拦截,后面再说-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">/login/noPermission.do</prop>
</props>
</property>
</bean>
<!-- 开启shiro注解-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
4、配置web.xml
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5、实现AuthorizingRealm,管理用户权限字符和角色
每次遇到需要权限鉴定的地方都会执行doGetAuthorizationInfo方法,我们再这里只要把用户的权限信息获取到交给SimpleAuthorizationInfo 就行
/**
* @author XuJD
* @create 2018-03-29 10:37
**/
public class UserRealm extends AuthorizingRealm{
private UserService userService = new UserServiceImpl();
/**
* 权限字符鉴权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
User user = (User) session.getAttribute(CommonConstants.LOGINED_USER);
if(user!=null){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
List<String> permissions = (List)session.getAttribute("permissionList");
List<String> roles = (List)session.getAttribute("roleTagList");
info.addStringPermissions(permissions);
info.addRoles(roles);
return info;
}
return null;
}
/**
* 角色鉴权
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
User user = (User) session.getAttribute(CommonConstants.LOGINED_USER);
if(user!=null){
//若存在,将此用户存放到登录认证info中
return new SimpleAuthenticationInfo(user.getAccountName(), user.getMail(), user.getId()+"");
}
return null;
}
}
6、获取用户权限信息
再用户登入成功后获取该用户的权限字符信息,扔到sesion中
//登入成功將用戶信息放入shiro的Subject中
UsernamePasswordToken token = new UsernamePasswordToken(user.getAccountName(),user.getMail());
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);
//获取当前用户角色ID集合
List<Long> roleIds = userRoleAuthorityService.findRoleIdsByUserId(user.getId());
//获取当前用户角色Tag集合
List<String> roleTagList = userRoleAuthorityService.findRoleTagByRoleIds(roleIds);
//获取当前用户所有权限字符
List<String> permissionList = roleResourceService.findPermissionsByRoleIds(roleIds);
session.setAttribute("permissionList",permissionList);
session.setAttribute("roleTagList",roleTagList);
7、使用
后端代码权限控制,用@RequiresPermissions注解
单个权限控制—@RequiresPermissions(“权限1”)
多个权限控制—@RequiresPermissions(value={“权限1”,”权限2”。。。}),逗号隔开
@RequiresPermissions(PermissionBasicConfig.configApply_dispatchConfigApply_cfgOdsTableTypeApply_delete)
@RequestMapping("/deleteTableType")
@ResponseBody
public ResultDO deleteTableType(@RequestParam int id){
cfgOdsTableTypeService.deleteTableType(id);
ResultDO<String> result = new ResultDO<String>();
result.setResult(true);
result.setResultMsg("删除成功");
return result;
}
页面权限控制,先引入shiro
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!-- 判断当前用户是否已经认证,已认证就可以看到标签中的内容 -->
<shiro:authenticated>
看到内容就说明你已经认证成功了!
</shiro:authenticated>
<br>
<!-- 判断当前用户是否拥有指定的权限 -->
<shiro:hasPermission name="权限1">
<input value="这是判断权限的按钮">
</shiro:hasPermission>
<br>
<!-- 判断当前用户是否拥有指定的角色 -->
<shiro:hasRole name="admin">
<input value="这是判断角色的按钮">
</shiro:hasRole>
关于shiro还有很多值得学习的东西,有兴趣可以去深入了解