一, 简介:
shiro 是一个安全框架, 顾名思义就是对系统的访问进行安全控制, 包含用户身份认证 (登录), 用户权限控制 (通过角色, 权限字符串等).
权限里面很关键的两个东西: 认证和授权.
1. 认证没什么好说的, 目的就是判断用户的账号密码是否正确之类的, 授权的作用嘛, 简单的解释就是给用户赋予相应的权限.
2. 判断一个用户有没有权限访问, 无非是拦截 URL 能否访问, 分为以下几个操作
1 判断当前 URL 是否需要拦截, 不需要则放行, 需要则进入下一步
2 判断用户是否已登陆, 有则下一步, 无则抛出 401 未认证
4 从资源表 / 权限表读取当前登陆用户的可访问地址, 进入下一步判断是否包含用户当前访问的地址, 有则放行, 无则抛出 403 无权限.
二, 简单搭建
1.maven 工程, 版本自行选择
- org.apache.shiro
- shiro-core
- 1.3.2
- org.apache.shiro
- shiro-web
- 1.3.2
- org.apache.shiro
- shiro-spring
- 1.3.2
- org.apache.shiro
- shiro-ehcache
- 1.3.2
2. 配置 Web.xml, 需要配置 shiro 特定的过滤器, 主要作用是把所有的 bean 交给 spring 管理, 通过 spring 容器来管理 filter 的生命周期, 通过 spring 注入的形式, 来代理一个 filter 执行, 主要目的是, 找到在 spring 中维护的目标 filter.
shiro 权限拦截
- shiroFilter
- org.springframework.Web.filter.DelegatingFilterProxy
- targetFilterLifecycle
- true
- shiroFilter
- /*
- contextConfigLocation
- classpath:conf/spring/spring-shiro.xml
- xml version="1.0" encoding="UTF-8" ?>
- xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance https://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context" xmlns:rsf="http://www.suning.com/schema/rsf"
- xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.suning.com/schema/rsf http://www.suning.com/schema/rsf/rsf.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
- ;
- id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- name="securityManager" ref="securityManager" />
- id="exceptionResolver" class="com.suning.lCSS.common.util.MyExceptionResolver">
- id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- name="realm" ref="customRealm" />
- id="customRealm" class="com.suning.lcss.base.shiro.ShiroDbRealm">
- class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- name="securityManager" ref="securityManager" />
exceptionResolver 作用在于统一的异常捕捉.
ShiroDbRealm 类中有 doGetAuthorizationInfo(AuthenticationToken token) ,doGetAuthenticationInfo 两个方法, doGetAuthenticationInfo(PrincipalCollection arg0) 作用在于登陆认证, 包括用户名和密码的验证, 如果不做用户名密码的验证.
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- UsernamePasswordToken upToken =(UsernamePasswordToken)token;
- String userName=upToken.getUsername();
- return new SimpleAuthenticationInfo(userName,
- upToken.getPassword(),getName());
- }
- /**
- * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用, 负责在应用程序中决定用户的访问控制的方法
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
- UserLoginBean user = (UserLoginBean) SecurityUtils.getSubject().getSession().getAttribute(LcssConstant.LOGIN_COMMAND);
- SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
- info.addRole(user.getRoleCode());
- // 权限编码
- String authorityStr = CommonUtil.getAuthorityStr(user.getInitialFlag(), user.getRoleCode());
- List<String> idList = new ArrayList<>();
- if(!StringUtil.isNullOrEmpty(authorityStr)){
- idList = Arrays.asList(authorityStr.split(","));
- }
- info.addStringPermissions(idList);
- return info;
- }
doGetAuthorizationInfo(PrincipalCollection arg0), 每次 controller 层调用都会进入这个方法来判断当前用户是否有权限. 如果有权限进入方法, 没权限拒绝访问.
注解 RequiresPermissions 的使用: br/>@RequestMapping("/addWorkOrderSureMessage.th")
@RequiresPermissions(value = {"1001"})
RequiresPermissions 放在 controller 层中, 控制访问, 每次访问当前方法, 都会进入 doGetAuthorizationInfo(PrincipalCollection arg0) 进行权限认证, 包含 1001 权限才能进入方法, 否则验证不通过.
三, 总结:
Shiro 可以帮助我们完成: 认证, 授权, 加密, 会话管理, 与 Web 集成, 缓存等.
Realm 是 Shiro 的核心组建, 也一样是两步走, 认证和授权, 在 Realm 中的表现为以下两个方法.
认证: doGetAuthenticationInfo, 核心作用判断用户名密码是否正确
授权: doGetAuthorizationInfo, 核心作用是获取用户的权限字符串, 用于后续的判断
Authentication: 身份认证 / 登录, 验证用户是不是拥有相应的身份;
Authorization: 授权, 即权限验证, 验证某个已认证的用户是否拥有某个权限; 即判断用户是否能做事情, 常见的如: 验证某个用户是否拥有某个角色. 或者细粒度的验证某个用户对某个资源是否具有某个权限;
来源: http://www.bubuko.com/infodetail-3333633.html