说实话开学第一周效率并不高。项目该结的都差不多结了,看来这毛病我是养成了。项目忙的要死的时候,想休息想停一停就不断往下扔包袱。一下没项目了开学了,反倒开始手痒,捉摸着写点什么代码。马上我的小mac就要送去维修了,我这寂寞可能会难耐。
还是整理总结一下shiro吧,要不这周光学个这可就白学了。
shiro我觉得很简单,简单易上手的框架,不仅对授权与权限的控制简单,对细粒度的权限也很方便。
重要的两个方法一个是doGetAuthorizationInfo和doGetAuthenticationInfo,一个是授权一个是认证,确实很像。
Authentication n.证明、鉴定、证实。 Authorization n.授权、认可、委任。(记住方法,正常流程先认证再授权,它俩Auth之后的e和o,e在前e就是认证,o就是授权)。
Principals(身份):是Subject 的‘identifying attributes(标识属性)’。比如我们登录提交的用户名。
Credentials(凭证):通常是只被Subject 知道的秘密值,它用来作为一种起支持作用的证据,此证据事实上包含着所谓的身份证明。比如我们登录提供的密码。
搭框架,正常套路。
1、放jar或配maven,配置shiroFilter在web.xml。
2、spring整合配置
<!-- 配置自定义Realm --> <bean id="myRealm" class="com.crossoverJie.shiro.MyRealm"/> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"/> </bean> <!-- Shiro过滤器 核心--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager"/> <!-- 身份认证失败,则跳转到登录页面的配置 --> <property name="loginUrl" value="/login.jsp"/> <!-- 权限认证失败,则跳转到指定页面 --> <property name="unauthorizedUrl" value="/nopower.jsp"/> <!-- Shiro连接约束配置,即过滤链的定义 --> <property name="filterChainDefinitions"> <value> <!--anon 表示匿名访问,不需要认证以及授权--> /loginAdmin=anon <!--authc表示需要认证 没有进行身份认证是不能进行访问的--> /admin*=authc /student=roles[teacher] /teacher=perms["user:create"] </value> </property> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 开启Shiro注解 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>
3、去搞个realm,最终处理都将交给Real进行处理。继承AuthorizingRealm类,复写上面提到的两个Auth方法。
这时会调用Realm的getAuthenticationInfo(token)方法。
该方法主要执行以下操作:
1、检查提交的进行认证的令牌信息
2、根据令牌信息从数据源(通常为数据库)中获取用户信息
3、对用户信息进行匹配验证。
4、验证通过将返回一个封装了用户信息的AuthenticationInfo实例。
5、验证失败则抛出AuthenticationException异常信息。
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; User user = accountManager.findUserByUserName(token.getUsername()); if (user != null) { return new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), getName()); } else { return null; } }
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String userName = (String) principals.fromRealm(getName()).iterator().next(); User user = accountManager.findUserByUserName(userName); if (user != null) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); for (Group group : user.getGroupList()) { info.addStringPermissions(group.getPermissionList()); } return info; } else { return null; } }
Shiro提供的注解
@RequiresAuthentication :要求当前 Subject 已经在当前的session 中被验证通过才能被注解的类/实例/方法访问或调用。
@RequiresGuest :要求当前的 Subject 是一个 “guest”,也就是他们必须是在之前的 session 中没有被验证或记住才能被注解的类/实例/方法访问或调用。
@RequiresPermissions:要求当前的 Subject 被允许一个或多个权限,以便执行注解的方法,比如:@RequiresPermissions("account:create") @RequiresRoles:要求当前的 Subject 拥有所有指定的角色。如果他们没有,则该方法将不会被执行,而且 AuthorizationException 异常将会被抛出。比如:@RequiresRoles("administrator")
@RequiresUser:需要当前的Subject 是一个应用程序用户才能被注解的类/实例/方法访问或调用。要么是通过验证被确认,或者在之前session 中的 'RememberMe‘ 服务被记住。
心声 〔奥〕 里尔克
遮住我的双眼,我依然能看见你。
捂住我的双耳,我依然能听见你。
没有了双脚,我依然能走向你。
没有了双唇,我依然能呼唤你。
折断我的手臂,我依然能用我的心代替双手拥抱你的影子。
摘去我的心脏,我的大脑依然在跳动。
即使我的大脑被烧毁,
我依然能用全身的血液托浮起你。
晚安 ,futureGirl 看着你,所以加油。