5

Я пытаюсь использовать JavaConfig вместо конфигурации XML для Spring Security. Я хотел бы использовать @PreAuthorization для объявления прав доступа.Spring Security Java Config

My Spring Security Config выглядит следующим образом:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { 
     auth 
      .inMemoryAuthentication() 
      .withUser("user").password("password").roles("USER"); 
    } 
} 

Однако, это не работает. После развертывания моего веб-приложения я получаю сообщение об ошибке Error creating bean with name 'methodSecurityInterceptor' defined in class path resource.

После некоторых исследований выяснилось, что я должен добавить библиотеку aopalliance в свой проект. К сожалению, это не решило мою проблему.

Вот полный трассировки стека:

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 java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:592) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) 
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1558) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:620) 
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:567) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1487) 
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97) 
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328) 
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420) 
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:848) 
    at sun.reflect.GeneratedMethodAccessor42.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322) 
    at sun.rmi.transport.Transport$1.run(Transport.java:177) 
    at sun.rmi.transport.Transport$1.run(Transport.java:174) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 
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 java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188) 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581) 
    ... 56 more 
Caused by: java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] 
    at org.springframework.util.Assert.isTrue(Assert.java:65) 
    at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.lazyBean(GlobalMethodSecurityConfiguration.java:352) 
    at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.authenticationManager(GlobalMethodSecurityConfiguration.java:240) 
    at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor(GlobalMethodSecurityConfiguration.java:116) 
    at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerByCGLIB$$890899ea.CGLIB$methodSecurityInterceptor$2(<generated>) 
    at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerByCGLIB$$890899ea$$FastClassByCGLIB$$fba343c4.invoke(<generated>) 
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) 
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326) 
    at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerByCGLIB$$890899ea.methodSecurityInterceptor(<generated>) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166) 
    ... 57 more 
+0

Опубликовать стек, который вы получите. –

+0

Здесь мы идем .. https://gist.github.com/mhmpl/8020820 – mhmpl

+0

Пожалуйста, добавьте его на свой вопрос. Просто стоп-трек не ссылка. Также какую версию Spring Security вы используете? Текущая версия не имеет метода, который вы переопределите. –

ответ

5

из StackTrace, у вас нет аутентификации менеджера defiend правильно:

Caused by: java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] 

Вот рабочий пример:

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth 
      .inMemoryAuthentication() 
       .withUser("user").password("password").roles("USER"); 
    } 
} 

Просто добавьте глобальную аннотацию метода и измените метод, чтобы он не переопределялся и не был autowi красный.

8

Согласно вашему стеклу, в вашем контексте нет фанеры AuthenticationManager.

Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] 

кажется, что вам нужно явно выставить AuthenticationManager как фасоль; попробуйте следующее:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication() 
      .withUser("user").password("password").roles("USER"); 
    } 

    @Bean @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 
} 
+0

Работа с 'AuthenticationManager' как' @ Bean' работает для разрешения данной ошибки.Но для меня это вызвало другие ошибки, возможно потому, что это эффективно замыкает «AuthenticationManagerBuilder». – Koraktor

+0

Нет, это не короткое замыкание 'AuthenticationManagerBuilder'. Взгляните на реализацию [WebSecurityConfigurerAdapter] (https://github.com/spring-projects/spring-security/blob/3.2.0.RELEASE/config/src/main/java/org/springframework/security/config /annotation/web/configuration/WebSecurityConfigurerAdapter.java). –

+0

Хорошо, может быть, неудачный выбор слов. Похоже, что это обходное решение делает короткую замыкание * полной конфигурации * «AuthenticationManagerBuilder». Просто, чтобы быть ясным: у меня все еще есть эта проблема в моем приложении, и каждое обходное решение, которое я пытался, привело к другим ошибкам. Для меня кажется, что '@ EnableGlobalMethodSecurity' работает только для приложений с довольно простыми конфигурациями безопасности. – Koraktor

1

Как отмечает NimChimpsky, Spring 3.2.0.RELEASE требует обновления конфигурации.

Используя эту конфигурацию, я получал точно такое же исключение, как и OP, но только в половине случаев. Другая половина времени, когда приложение запускалось просто отлично. Я предполагаю, что есть какое-то состояние гонки.

Первоначально я тянул конфигурацию безопасности при использовании @Import на моей конфигурации корня:

@Configuration 
@Import(SecurityConfig.class) 
... other annotations ... 
public class RootConfig { 
    ... 
} 

Когда я заменил, что с

public class WebAppInit extends AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return new Class<?>[] { RootConfig.class, SecurityConfig.class }; 
    } 
} 

проблема ушла. Не погрузился в причины, почему, поэтому я не могу с этим поговорить, но вы можете попробовать.

0

В моем случае у меня есть линия super.configure(auth); в основном методе configure(AuthenticationManagerBuilder auth).

После того, как оно было удалено, исключение исчезло.

Смежные вопросы