开发系统中,少不了权限,目前java里的权限框架有SpringSecurity和Shiro(以前叫做jsecurity),对于SpringSecurity:功能太过强大以至于功能比较分散,使用起来也比较复杂,跟Spring结合的比较好。对于初学SpringSecurity者来说,曲线还是较大,需要深入学习其源码和框架,配置起来也需要费比较大的力气,扩展性也不是特别强。
对于新秀Shiro来说,好评还是比较多的,使用起来比较简单,功能也足够强大,扩展性也较好。听说连Spring的官方都不用SpringSecurity,用的是Shiro,足见Shiro的优秀。网上找到两篇介绍:http://www.infoq.com/cn/articles/apache-shirohttp://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/,官网http://shiro.apache.org/,使用和配置起来还是比较简单。下面只是简单介绍下我们是如何配置和使用Shiro的(暂时只用到了Shiro的一部分,没有配置shiro.ini文件)。
首先是添加过滤器,在web.xml中:
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <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> |
权限的认证类:
publicclassShiroDbRealmextendsAuthorizingRealm{ @Inject privateUserServiceuserService;
/** *认证回调函数,登录时调用. */ protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthcToken) UsernamePasswordTokentoken=(UsernamePasswordToken)authcToken; Useruser=userService.getUserByUserId(token.getUsername()); if(user!=null){ returnnewSimpleAuthenticationInfo(user.getUserId(),user.getUserId(),getName()); }else{ returnnull; } } /** *授权查询回调函数,进行鉴权但缓存中无用户的授权信息时调用. */ protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){ StringloginName=(String)principals.fromRealm(getName()).iterator().next(); Useruser=userService.getUserByUserId(loginName); if(user!=null){ SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo(); info.addStringPermission("common-user"); returninfo; }else{ returnnull; } } } |
Spring的配置文件:
<?xmlversion="1.0"encoding="UTF-8"?> <beans> <description>ShiroConfiguration</description> <beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/> <beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <propertyname="realm"ref="shiroDbRealm"/> </bean> <beanid="shiroDbRealm"class="com.company.service.common.shiro.ShiroDbRealm"/> <beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <propertyname="securityManager"ref="securityManager"/> <propertyname="loginUrl"value="/common/security/login"/> <propertyname="successUrl"value="/common/security/welcome"/> <propertyname="unauthorizedUrl"value="/common/security/unauthorized"/> <propertyname="filterChainDefinitions"> <value> /resources/**=anon /manageUsers=perms[user:manage] /**=authc </value> </property> </bean> <beanid="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"/> <beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <propertyname="securityManager"ref="securityManager"/> </bean> </beans> |
登录的Controller:
@Controller @RequestMapping(value="/common/security/*") publicclassSecurityController{ @Inject privateUserServiceuserService; @RequestMapping(value="/login") publicStringlogin(StringloginName,Stringpassword, Useruser=userService.getUserByLogin(loginName); if(null!=user){ setLogin(loginInfoVO.getUserId(),loginInfoVO.getUserId()); return"redirect:/common/security/welcome"; }else{ return"redirect:/common/path?path=showLogin"; } }; publicstaticfinalvoidsetLogin(StringuserId,Stringpassword){ SubjectcurrentUser=SecurityUtils.getSubject(); if(!currentUser.isAuthenticated()){ //collectuserprincipalsandcredentialsinaguispecificmanner //suchasusername/passwordhtmlform,X509certificate,OpenID,etc. //We'llusetheusername/passwordexampleheresinceitisthemostcommon. //(doyouknowwhatmoviethisisfrom?;) UsernamePasswordTokentoken=newUsernamePasswordToken(userId,password); //thisisallyouhavetodotosupport'rememberme'(noconfig-builtin!): token.setRememberMe(true); currentUser.login(token); } };
@RequestMapping(value="/logout") @ResponseBody publicvoidlogout(HttpServletRequestrequest){ Subjectsubject=SecurityUtils.getSubject(); if(subject!=null){ subject.logout(); } request.getSession().invalidate(); }; } |
注册和获取当前登录用户:
publicstaticfinalvoidsetCurrentUser(Useruser){ SubjectcurrentUser=SecurityUtils.getSubject(); if(null!=currentUser){ Sessionsession=currentUser.getSession(); if(null!=session){ session.setAttribute(Constants.CURRENT_USER,user); } } }; publicstaticfinalUsergetCurrentUser(){ SubjectcurrentUser=SecurityUtils.getSubject(); if(null!=currentUser){ Sessionsession=currentUser.getSession(); if(null!=session){ Useruser=(User)session.getAttribute(Constants.CURRENT_USER); if(null!=user){ returnuser; } } } }; |
需要的jar包有3个:shiro-core.jar,shiro-spring.jar,shiro-web.jar。感觉shiro用起来比SpringSecurity简单很多