启动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>
@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();
}
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。