2014-07-24 10 views
8

Ich möchte Methoden Sicherheit implementieren.Nochmals ... Methode Sicherheit mit Spring Boot/Sicherheit: Fehler beim Erstellen Bean mit dem Namen 'methodSecurityInterceptor' "Dieses Objekt wurde bereits gebaut"

Ich habe ein Problem mit @Secured und @ PreAuth Annotationen. Jedes Mal, wenn ich eines dieser Elemente zu meiner Serviceschnittstelle hinzufüge, erhalte ich eine Ausnahme wie die folgende. Ohne sie läuft meine App gut.

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 

Es ist eine REST-Dienstanwendung.

Hier sind einige relevante Teile meiner Konfiguration. Bitte lassen Sie mich wissen, ob ich noch etwas hinzufügen soll.

@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"); 
    } 
} 

Und:

@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); 
    } 
... 
} 

Nach AlreadyBuiltException documentation:

Geworfen wenn AbstractSecurityBuilder.build() ist zwei oder mehr Male.

Aber ich kann nicht herausfinden, warum der Frühling das macht.

Alle Ponters würden sehr geschätzt werden.

Danke euch allen.

Hier habe ich etwas mehr 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 




////// Update 1 //////

Basierend auf @ M.Dainum habe ich meine authenticationManager entfernt.

Versucht, meine auf drei Arten (in diesem Beitrag enthalten) zu definieren, aber alle führten zu der gleichen NullPointerException bei der Authentifizierung.

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:

 if (!provider.supports(toTest)) { 
- Ich glaube nicht, `provider` null ist, da ich sicher, dass meine gemacht autowired` databaseAuthenticationProvider` war es nicht.
- `toTest` kommt von` authentication.getClass() `. Es sollte nicht null sein. Recht?(Nicht sicher, ob ich verstanden Ferne das Problem)


getProviders() contins:

[null, org.springfr[email protected]490adcdf]

Einen Fehler gemacht vorher: Der Anbieter ist null. So ist das "Autowiriring" nicht möglich.

Ich denke, das ist, weil, um etwas wie zu verwenden: auth.authenticationProvider(databaseAuthenticationProvider);, databaseAuthenticationProvider sollte statisch sein und das verhindert die Autowiring. Recht?

Wenn ich es mit "neu" erstellen, dann ist danach messageDigestPasswordEncoder null, und so weiter.

Also ... Wie soll ich das lösen?

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); 
    } 




////// Update 2 //////

zu "zwingen", die "Autowiriring", versuchte @Autowire aus dem Attribut zu entfernen, und fügen Sie es auf eine Setter-Methode wie folgt aus:

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); 
     } 

Und jetzt: ein bis squere zurück:

Ursache: org.springframework.beans.factory.BeanDefinitionStoreException: Factory-Methode [public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor() gibt java.lang aus .Exception] hat Ausnahme ausgelöst; verschachtelte Ausnahme ist org.springframework.security.config.annotation.AlreadyBuiltException: Dieses Objekt wurde bereits

gebaut ich das Problem war nicht erraten, dass ich meine eigenen AuthenticationManager somehwere sonst hatte zweimal gebaut.

Wie finde ich es?

Übrigens ...es hat immer noch Null-Wert:

************************************** *********** databaseAuthenticationProvider es null

+0

Sie sollten weder Ihren eigenen 'AuthenticationManager' erstellen noch die' build' Methode aufrufen müssen. Erstellen Sie einfach eine 'configure'-Methode in Ihrem' RestWebSecurityConfigurationAdapter' und rufen Sie in dieser Methode einfach den 'authenticationProvider' auf, wie Sie es jetzt tun. Das sollte alles sein, was benötigt wird. Sie müssen auch sicherstellen, dass Sie Ihre Konfiguration nicht zweimal laden (zum Beispiel versehentlich). –

+0

Aber ich habe meinen eigenen databaseAuthenticationProvider. Wie sollte ich es sonst konfigurieren? – elysch

+1

Indem ich es einfach mit dem Aufruf der Methode 'authenticationProvider' auf dem mitgelieferten 'AuthenticationManagerBuilder' anwähle, wie ich auch in meinem vorherigen Kommentar erwähnt habe. –

Antwort

2

Ich möchte M.Deinum danken. Ich habe es endlich funktioniert.

Es ist so einfach, wie folgt aus:

@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() 
... 

Nun meine Service-Methode zugänglich ist nur durch die angegebene Rolle wie folgt aus:

@Secured({Sec.R_ADMIN}) 
Usuario getUsuarioByEmisorAndIdUsuario(Emisor emisor, String idUsuario, boolean consultarRoles) throws AuthorizationException; 

Being:

public class Sec { 
    public static final String R_ADMIN = "ROLE_ADMIN"; 
2

Nach mehreren Stunden getestet jede Option, es funktionierte für mich auf diese Weise:

@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 
    } 
} 
+0

Das Hinzufügen von @EnableWebSecurity hat mein Problem gelöst. –

Verwandte Themen