版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yueloveme/article/details/85019864
大家推荐个靠谱的公众号程序员探索之路,大家一起加油,这个公众号已经接入图灵
最近一个小伙伴需要用到shiro我就顺变弄了一份,还有很多需要完善的地方,以后慢慢完善。目前可以实现用户角色,权限,自定义realm,会话管理的功能
shiro配置文件
<bean id="shiroSessionListener" class="com.zzh.shiro.listener.ShiroSessionListener"></bean> <!--filter配置策略--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/index"/> <!--登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。--> <property name="successUrl" value="/home"/> <!--unauthorizedUrl:没有权限默认跳转的页面。--> <property name="unauthorizedUrl" value="/unauthorized.jsp"/> <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean --> <!-- defined will be automatically acquired and available via its beanName in chain --> <!-- definitions, but you can perform instance overrides or name aliases here if you like: --> <!-- <property name="filters"> <util:map> <entry key="logout" value-ref="logoutFilter" /> </util:map> </property> --> <property name="filterChainDefinitions"> <value> /login = anon /logout = anon /error = anon /** = user </value> </property> </bean> <!--会话管理--> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- 设置全局会话超时时间,默认30分钟,即如果30分钟内没有访问会话将过期 1800000 --> <property name="globalSessionTimeout" value="1800000"/> <!-- 删除失效的session --> <property name="deleteInvalidSessions" value="true"/> <!-- 是否开启会话验证器,默认是开启的 --> <property name="sessionValidationSchedulerEnabled" value="true"/> <property name ="sessionListeners"> <list> <ref bean="shiroSessionListener"/> </list> </property> </bean> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm" /> <property name="cacheManager" ref="cacheManager" /> <property name="sessionManager" ref="sessionManager"></property> </bean> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <bean id="myRealm" class="com.zzh.shiro.dao.UserRealm"></bean> <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /> <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>
监听器:
package com.zzh.shiro.listener; import org.apache.shiro.SecurityUtils; import org.apache.shiro.session.Session; import org.apache.shiro.session.SessionListenerAdapter; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.DefaultSubjectContext; import org.apache.shiro.subject.support.DelegatingSubject; import org.apache.shiro.web.subject.support.WebDelegatingSubject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * shiro 会话监听 */ public class ShiroSessionListener extends SessionListenerAdapter { Logger logger=LoggerFactory.getLogger(ShiroSessionListener.class); @Override public void onStart(Session session) {//会话创建时触发 logger.debug("会话创建:" + session.getId()); } @Override public void onExpiration(Session session) {//会话过期时触发 logger.debug("会话过期:" + session.getId()); } @Override public void onStop(Session session) {//退出时触发 logger.info("会话停止:" + session.getId()); } }
realm:
package com.zzh.shiro.dao; import com.zzh.shiro.service.UsersService; import org.apache.shiro.authc.*; 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 java.util.HashSet; import java.util.List; import java.util.Set; public class UserRealm extends AuthorizingRealm { @Autowired private UsersService userService; @Autowired private UsersDAO userDao; /** * 授权 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 获取用户名 String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //用户角色 Set<String> roles = new HashSet<String>(userDao.getRoles(username)); authorizationInfo.setRoles(roles); //用户权限 Set<String> permissions = new HashSet<String>(userDao.getUserPermissions(username)); //查找额外权限 List<String> permission2 = userDao.getPermission2(username); if (null != permission2 && !permission2.isEmpty()){ permissions.addAll(permission2); } authorizationInfo.setStringPermissions(permissions); return authorizationInfo; } /** * 认证 * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String username = (String) authenticationToken.getPrincipal(); String password = userDao.getPassword(username); // 查出是否有此用户 if (password == null) { throw new UnknownAccountException();// 没找到帐号 } // 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现 //, 这个是用户密码加盐 ByteSource.Util.bytes(user.getCredentialsSalt()), getName() SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName()); return authenticationInfo; } @Override public void clearCachedAuthorizationInfo(PrincipalCollection principals) { super.clearCachedAuthorizationInfo(principals); } @Override public void clearCachedAuthenticationInfo(PrincipalCollection principals) { super.clearCachedAuthenticationInfo(principals); } @Override public void clearCache(PrincipalCollection principals) { super.clearCache(principals); } public void clearAllCachedAuthorizationInfo() { getAuthorizationCache().clear(); } public void clearAllCachedAuthenticationInfo() { getAuthenticationCache().clear(); } public void clearAllCache() { clearAllCachedAuthenticationInfo(); clearAllCachedAuthorizationInfo(); } } 完整代码地址:https://github.com/ZhZGod/shiro-study.git