启动web时报如下警告:
17:12:54.027 [localhost-startStop-1] WARN [org.springframework.beans.factory.support.AbstractBeanFactory-getTypeForFactoryBean-1416]-Bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'shiroFilter': Requested bean is currently in creation: Is there an unresolvable circular reference?
我的配置和实现:
shiro配置:
<?xml version="1.1" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-lazy-init="true"> <description>Shiro安全配置</description> <!-- 读取配置文件 --> <context:property-placeholder ignore-unresolvable="true" location="classpath*:/application.properties" /> <!-- Shiro的主要业务层对象基于web的应用程序 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="userRealm" /> <property name="cacheManager" ref="shiroEhcacheManager" /> </bean> <!-- Shiro Filter --> <bean id="myCaptchaFilter" class="com.dt.system.utils.FormAuthenticationCaptchaFilter" /> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="${adminPath}/login" /> <property name="successUrl" value="${adminPath}" /> <property name="filters"> <map> <entry key="authc" value-ref="myCaptchaFilter" /> </map> </property> <property name="filterChainDefinitions"> <value> /static/** = anon /system/user/checkUser = anon ${adminPath}/login = authc ${adminPath}/** = user /rest/**=authcBasic </value> </property> </bean> <!-- 用户授权信息Cache, 采用EhCache --> <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:cache/ehcache-shiro.xml" /> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!-- AOP式方法级权限检查 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true" /> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </beans>
realm的实现:
@Service @DependsOn({ "userMapper", "permissionMapper", "roleMapper" }) public class UserRealm extends AuthorizingRealm { private static Logger logger = LoggerFactory.getLogger(UserRealm.class); @Autowired protected UserService userService; @Autowired protected PermissionService permissionService; @Autowired protected RoleService roleService; /** * 认证回调函数,登录时调用. */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordCaptchaToken token = (UsernamePasswordCaptchaToken) authcToken; User user = userService.getUser(token.getUsername()); if (user != null && doCaptchaValidate(token)) { byte[] salt = Encodes.decodeHex(user.getSalt()); ShiroUser shiroUser = new ShiroUser(user.getId(), user.getLoginName(), user.getName()); // 设置用户session Session session = SecurityUtils.getSubject().getSession(); session.setAttribute("user", user); return new SimpleAuthenticationInfo(shiroUser, user.getPassword(), ByteSource.Util.bytes(salt), getName()); } else { logger.info("设置失败"); return null; } } /** * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用. */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal(); User user = userService.getUser(shiroUser.loginName); // 把principals放session中 key=userId value=principals SecurityUtils.getSubject().getSession().setAttribute(String.valueOf(user.getId()), SecurityUtils.getSubject().getPrincipals()); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 赋予角色 for (Role role : roleService.getRolesByUserId(user.getId())) { info.addRole(role.getName()); } // 赋予权限 for (Permission permission : permissionService.getPermissionsByUserId(user.getId())) { if (StringUtils.isNotBlank(permission.getPermCode())) info.addStringPermission(permission.getPermCode()); } // 设置登录次数、时间 userService.updateUserLogin(user); return info; } /** * 验证码校验 * * @param token * @return boolean */ protected boolean doCaptchaValidate(UsernamePasswordCaptchaToken token) { String captcha = (String) SecurityUtils.getSubject().getSession() .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())) { throw new CaptchaException("验证码错误!"); } return true; } /** * 设定Password校验的Hash算法与迭代次数. */ @SuppressWarnings("static-access") @PostConstruct public void initCredentialsMatcher() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(userService.HASH_ALGORITHM); matcher.setHashIterations(userService.HASH_INTERATIONS); setCredentialsMatcher(matcher); } /** * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息. */ public static class ShiroUser implements Serializable { private static final long serialVersionUID = -1373760761780840081L; public Integer id; public String loginName; public String name; public ShiroUser(Integer id, String loginName, String name) { this.id = id; this.loginName = loginName; this.name = name; } public Integer getId() { return id; } public String getName() { return name; } /** * 本函数输出将作为默认的<shiro:principal/>输出. */ @Override public String toString() { return loginName; } /** * 重载hashCode,只计算loginName; */ @Override public int hashCode() { return Objects.hashCode(loginName); } /** * 重载equals,只计算loginName; */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ShiroUser other = (ShiroUser) obj; if (loginName == null) { if (other.loginName != null) { return false; } } else if (!loginName.equals(other.loginName)) { return false; } return true; } } @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(); } }
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。