package com.gxx.manage.shiro; import java.util.List; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.log4j.Logger; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; 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 com.gxx.manage.base.vo.Permission; import com.gxx.manage.base.vo.Role; import com.gxx.manage.base.vo.User; import com.gxx.manage.service.UserService; /** *
*
Title:
*
* 自定义授权领域类 *
*
Description:
*
*

none *

*
* * @author Administrator * @version 1.0, 2015年9月19日 * @since manage * */ public class ManageAuthorizingRealm extends AuthorizingRealm { /** * 日志处理器 */ Logger logger = Logger.getLogger(ManageAuthorizingRealm.class); @Autowired UserService userService; /** * 为当前登录的Subject授予角色和权限 * @see 经测试:本例中该方法的调用时机为需授权资源被访问时 * @see 经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache * @see 个人感觉若使用了Spring3.1开始提供的ConcurrentMapCache支持,则可灵活决定是否启用AuthorizationCache * @see 比如说这里从数据库获取权限信息时,先去访问Spring3.1提供的缓存,而不使用Shior提供的AuthorizationCache */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { /** * 获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next() */ String currentUsername = (String)super.getAvailablePrincipal(principals); logger.info("为当前登录的Subject授予角色和权限,用户名:" + currentUsername); User user = userService.getUserByName(currentUsername); if(null == user){ /** * 不存在用户则返回null */ logger.error("不存在用户"); return null; } /** * 为当前用户查询角色和权限 */ SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo(); List roles = userService.queryRolesByUserId(user.getId()); for(Role role : roles){ logger.info("拥有角色:" + role.getRole()); simpleAuthorInfo.addRole(role.getRole()); List permissions = userService.queryPermissionsByRoleId(role.getId()); for(Permission permission : permissions){ logger.info("拥有权限:" + permission.getPermission()); simpleAuthorInfo.addStringPermission(permission.getPermission()); } } return simpleAuthorInfo; } /** * 验证当前登录的Subject */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { /** * 获取基于用户名和密码的令牌 * 实际上这个token是从LoginController里面currentUser.login(token)传过来的 * 两个token的引用都是一样的 */ logger.info("验证当前Subject时获取到token为" + ReflectionToStringBuilder. toString(((UsernamePasswordToken)token), ToStringStyle.MULTI_LINE_STYLE)); User user = userService.getUserByName(((UsernamePasswordToken)token).getUsername()); if(null == user){ /** * 不存在用户则返回null */ return null; } /** * 这里不用比较,直接返回就好,shiro会自动比较 */ AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo (user.getName(), user.getPassword(), this.getName()); return authenticationInfo; } }