我想实现方法安全性。
我遇到了@Secured和@PreAuth注释的问题。每当我将任何这些添加到我的服务接口时,我都会收到如下例外情况。没有它们,我的应用运行得很好。
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor() throws java.lang.Exception] threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
它是一个REST服务应用程序。
以下是我的配置的一些相关部分。如果我还要添加其他内容,请告诉我。
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {
...
@Autowired
private DatabaseAuthenticationProvider databaseAuthenticationProvider;
...
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/usuario/*/rfc/*").authenticated()
.antMatchers(HttpMethod.GET, "/usuario/*/rfc/*/").authenticated()
.antMatchers(HttpMethod.GET, "/usuario/*").authenticated()
.antMatchers(HttpMethod.GET, "/usuario/*/").authenticated()
...
}
}
@SuppressWarnings("unchecked")
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return new AuthenticationManagerBuilder(new NopPostProcessor()).authenticationProvider(databaseAuthenticationProvider).build();
}
@SuppressWarnings("rawtypes")
private static class NopPostProcessor implements ObjectPostProcessor {
@Override
public Object postProcess(Object object) {
return object;
}
};
@Bean
public MessageDigestPasswordEncoder messageDigestPasswordEncoder() {
return new MessageDigestPasswordEncoder("sha-256");
}
}
和
@Service("databaseAuthenticationProvider")
public class DatabaseAuthenticationProvider
extends AbstractUserDetailsAuthenticationProvider {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private MessageDigestPasswordEncoder messageDigestPasswordEncoder;
...
@Override
protected void additionalAuthenticationChecks(UserDetails arg0,
UsernamePasswordAuthenticationToken arg1)
throws AuthenticationException {
return;
}
@Override
protected UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
// logger.debug("Inside retrieveUser");
String password = (String) authentication.getCredentials();
String encryptedPassword = "";
if (StringUtils.hasText(password)) {
encryptedPassword = messageDigestPasswordEncoder.encodePassword(password, null);
}
//UserDetails user = null;
String expectedPassword = null;
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
WebAuthenticationDetails wad = null;
wad = (WebAuthenticationDetails) authentication.getDetails();
...
return new org.springframework.security.core.userdetails.User(
username,
password,
true, // enabled
true, // account not expired
true, // credentials not expired
true, // account not locked
authorities);
}
...
}
根据AlreadyBuiltException documentation:
当AbstractSecurityBuilder.build()是两次或更多次时抛出。
但我无法找出为什么春天会这样做。
非常感谢任何人。
谢谢大家。
我在这里添加了一些CallStack
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usuarioServiceImpl' defined in file [C:\Users\ely\Documents\Desarrollo\Spring\workspace-sts-3.5.1.RELEASE\ws-timbrado-backend\target\classes\mx\i4b\timbrado\service\entidades\UsuarioServiceImpl.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor() throws java.lang.Exception] threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
... 73 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor() throws java.lang.Exception] threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor.getAdvice(MethodSecurityMetadataSourceAdvisor.java:96) ~[spring-security-core-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.aop.aspectj.AspectJProxyUtils.isAspectJAdvice(AspectJProxyUtils.java:67) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.aop.aspectj.AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(AspectJProxyUtils.java:49) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.extendAdvisors(AspectJAwareAdvisorAutoProxyCreator.java:97) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:89) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:376) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:339) ~[spring-aop-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:421) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
... 82 common frames omitted
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor() throws java.lang.Exception] threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
... 101 common frames omitted
Caused by: org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:42) ~[spring-security-config-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration.getAuthenticationManager(AuthenticationConfiguration.java:78) ~[spring-security-config-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.authenticationManager(GlobalMethodSecurityConfiguration.java:248) ~[spring-security-config-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor(GlobalMethodSecurityConfiguration.java:119) ~[spring-security-config-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$d8bcec4.CGLIB$methodSecurityInterceptor$8(<generated>) ~[spring-core-4.0.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$d8bcec4$$FastClassBySpringCGLIB$$42ba89ef.invoke(<generated>) ~[spring-core-4.0.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312) ~[spring-context-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$d8bcec4.methodSecurityInterceptor(<generated>) ~[spring-core-4.0.3.RELEASE.jar:3.2.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_25]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_25]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
... 102 common frames omitted
////// 更新1 //////
根据@ M.Dainum,我删除了authenticationManager
。
试图以三种方式定义我的databaseAuthenticationProvider
(包括在这篇文章中),但是在认证时都导致了相同的NullPointerException。
java.lang.NullPointerException: null
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:147) ~[spring-security-core-3.2.3.RELEASE.jar:3.2.3.RELEASE]
ProviderManager.java:147:
<德尔> - 我不认为`provider`是空的,因为我确保我的自动连接`databaseAuthenticationProvider`不是。if (!provider.supports(toTest)) {
getProviders()
contins:
[null,org.springframework.security.authentication.AnonymousAuthenticationProvider@490adcdf]
之前犯了错误:提供者为空。所以&#34; Autowiriring&#34;没有发生。
我认为这是因为为了使用类似:auth.authenticationProvider(databaseAuthenticationProvider);
的内容,databaseAuthenticationProvider
应该是静态的,并且会阻止自动装配。正确?
如果我使用&#34; new&#34;创建它,那么之后messageDigestPasswordEncoder
为空,依此类推。
那么......我该如何解决这个问题呢?
OP1:
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(databaseAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
Op2中:
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(databaseAuthenticationProvider);
OP3:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(databaseAuthenticationProvider);
}
////// 更新2 //////
To&#34; force&#34; &#34; Autowiriring&#34;,尝试从属性中删除@Autowire
并将其添加到这样的setter方法中:
public class WebSecurityConfig {
private static DatabaseAuthenticationProvider databaseAuthenticationProvider;
@Autowired
public void setDatabaseAuthenticationProvider(DatabaseAuthenticationProvider databaseAuthenticationProvider) {
WebSecurityConfig.databaseAuthenticationProvider = databaseAuthenticationProvider;
}
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if (databaseAuthenticationProvider == null) {
System.out.println("************************************************* databaseAuthenticationProvider es null");
} else {
System.out.println("************************************************* databaseAuthenticationProvider NO ES NULL");
}
auth.authenticationProvider(databaseAuthenticationProvider);
}
现在:回到squere one:
引起:org.springframework.beans.factory.BeanDefinitionStoreException:工厂方法[public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor()throws java.lang .Exception]抛出异常;嵌套异常是org.springframework.security.config.annotation.AlreadyBuiltException:此对象已经构建
我想问题不是我有自己的AuthenticationManager
其他人正在建造两次。
如何找到它?
顺便说一句......它仍然具有空值:
*************** ** databaseAuthenticationProvider es null
答案 0 :(得分:2)
我要感谢M.Deinum。我终于开始工作了。
就这么简单:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private DatabaseAuthenticationProvider databaseAuthenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(databaseAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/usuario/*/rfc/*").authenticated()
...
现在我的服务方法只能由指定的角色访问,如下所示:
@Secured({Sec.R_ADMIN})
Usuario getUsuarioByEmisorAndIdUsuario(Emisor emisor, String idUsuario, boolean consultarRoles) throws AuthorizationException;
存在:
public class Sec {
public static final String R_ADMIN = "ROLE_ADMIN";
答案 1 :(得分:2)
经过几个小时测试每个选项后,它对我有用:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
@Bean
public AuthenticationManager authenticationManager(AuthenticationProvider provider) {
return new ProviderManager(Arrays.asList(provider));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// here your permissions
}
}