题目描述
在登录后shiro没有进入Realm的doGetAuthorizationInfo方法,即使调用了subject.isPermitted方法也不行 希望懂shiro的大佬帮我解决一下 十分感谢!!
相关代码
ShiroAuthorizingRealm:
public class ShiroAuthorizingRealm extends AuthorizingRealm {
@Autowired
private IUserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("doGetAuthorizationInfo这里??");
// 已知用户名
// String username = principalCollection.getPrimaryPrincipal().toString();
ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
String username = shiroUser.getUserName();
// 资源:操作:id user:create
List<String> permissionList = this.userService.getUserPermssions(username);
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addStringPermissions(permissionList);
return simpleAuthorizationInfo;
}
/**
* 身份认证信息
* 重写该方法,从数据库中获取注册用户和对应的密码,封装成AuthenticationInfo对象返回
* */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// authenticationToken 当前登录用户的身份标识
// 已知用户名
System.out.println("身份认证信息doGetAuthenticationInfo这里??");
String username = authenticationToken.getPrincipal().toString();
// 再根据用户名从数据库中找密码
AuthSysUser user = this.userService.findByUserName(username);
if(user == null){
throw new AccountException("account not exist");
}
String password = user.getUrPassword();
// 用AuthenticationInfo对象,封装username和password
ShiroUser shiroUser = new ShiroUser();
shiroUser.setId(user.getUrId());
shiroUser.setUserName(user.getUrUserName());
shiroUser.setPassword(password);
shiroUser.setAuthCacheKey(user.getUrUserName()+user.getUrId());
SimpleAuthenticationInfo info= new SimpleAuthenticationInfo(shiroUser, password, this.getName());
return info;
}
}
PermissionAuthFilter:权限过滤器
public class PermissionAuthFilter extends AccessControlFilter {
@Override
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
boolean bool = true;
// 拼凑当前请求url对应的权限字符串 /user/create?xxxxx
HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
String requestURI = httpRequest.getRequestURI();
String[] permStrs = requestURI.split("/");
if(permStrs != null && permStrs.length>2) {
String perm = permStrs[1]+":"+permStrs[2];
// 资源名称:操作:对象id
// user:create,update,delete,search,other:*
// shop:create,update,delete...:*
// who what how
// 获取当前用户对应的subject对象
Subject subject = this.getSubject(servletRequest,servletResponse);
//Object primary = subject.getPrincipals().getPrimaryPrincipal();
// 调用subject对象的方法,判断是否有权限
// 返回判断结果
bool = subject.isPermitted(perm);
// bool = subject.hasRole(perm);
System.out.println(subject.hasRole(perm));
}
bool = true;
return bool;
}
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
((HttpServletRequest)servletRequest).getRequestDispatcher("/auth/noAuth").forward(servletRequest,servletResponse);
return false;
}
}
ShiroConfiguration类:
@Configuration
@Slf4j
public class ShiroConfiguration {
@Autowired
private RedisUtil redisUtil;
private TokenAuthFilter tokenAuthFilter;
private PermissionAuthFilter permissionAuthFilter;
@Autowired
private IPermissionService permissionService;
private static final String CACHE_KEY = "shiro:cache:";
private static final String SESSION_KEY = "shiro:session:";
private static final String NAME = "custom.name";
private static final String VALUE = "/";
@Bean("shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 创建一个Map对象包含所有要集成到Shiro框架中去的filter对象
// 注册哪些过滤器
Map<String, Filter> filters = new HashMap<String, Filter>();
// <filter>
// <filter-mapping
this.tokenAuthFilter = new TokenAuthFilter();
this.tokenAuthFilter.setRedisUtil(this.redisUtil);
this.permissionAuthFilter = new PermissionAuthFilter();
filters.put("authcToken", this.tokenAuthFilter);
filters.put("permAuthc", this.permissionAuthFilter);
// 在shiro中注册过滤器
shiroFilterFactoryBean.setFilters(filters);
// 设置哪些过滤器拦截哪些请求
Map<String,String> permChainMap = new HashMap<>();
//permChainMap.put("/user/**", "tokenAuthc");
List<AuthSysPermission> permissionList = this.permissionService.searchPermissions();
if(permissionList != null){
for(AuthSysPermission permission:permissionList){// /user/**
permChainMap.put("/"+permission.getResources().getRscUrl()+"/**", "authcToken, permAuthc");
}
}
shiroFilterFactoryBean.setFilterChainDefinitionMap(permChainMap);
// 其它的设置
shiroFilterFactoryBean.setLoginUrl("/auth/login");
//shiroFilterFactoryBean.setSuccessUrl();
shiroFilterFactoryBean.setUnauthorizedUrl("/auth/noAuth");
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
@Bean("securityManager") // 固定!
public DefaultWebSecurityManager createSecurityManager(@Qualifier("shiroRealm") ShiroAuthorizingRealm shiroRealm){
System.out.println("createSecurityManager这里?");
// 创建SecurityMananger对象,并且装配Realm对象
DefaultWebSecurityManager manager = new DefaultWebSecurityManager(shiroRealm);
// 自定义缓存实现 使用redis
manager.setCacheManager(cacheManager());
// 自定义session管理 使用redis
manager.setSessionManager(sessionManager());
/*
* 关闭shiro自带的session,详情见文档
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
manager.setSubjectDAO(subjectDAO);
manager.setRealm(shiroRealm);
return manager;
}
/**
* Session Manager
* 使用的是shiro-redis开源插件
*/
@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(redisSessionDAO());
// 允许支持基于Cookie传递的会话id
sessionManager.setSessionIdCookieEnabled(true);
// 支持请求的url重新(通过url传递会话id)
sessionManager.setSessionIdUrlRewritingEnabled(true);
SimpleCookie simpleCookie = new SimpleCookie();
simpleCookie.setName(NAME);
simpleCookie.setValue(VALUE);
// 设置传递会话id的cookie的属性
sessionManager.setSessionIdCookie(simpleCookie);
return sessionManager;
}
// 准备RedisSessionDAO
/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
* 使用的是shiro-redis开源插件
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
redisSessionDAO.setExpire(86400);
redisSessionDAO.setKeyPrefix(SESSION_KEY);
return redisSessionDAO;
}
/**
* cacheManager 缓存 redis实现
* 使用的是shiro-redis开源插件
*
* @return
*/
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
// 装配redisManager
redisCacheManager.setRedisManager(redisManager());
redisCacheManager.setExpire(86400);
redisCacheManager.setKeyPrefix(CACHE_KEY);
return redisCacheManager;
}
/**
* 配置shiro redisManager
* 使用的是shiro-redis开源插件
*
* @return
*/
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost("127.0.0.1");
redisManager.setPort(6379);
redisManager.setTimeout(0);
// redisManager.setPassword(password);
return redisManager;
}
}