spring boot(1.3)基于oauth2资源服务器:不能使用@PreAuthorize方法安全

Posted

技术标签:

【中文标题】spring boot(1.3)基于oauth2资源服务器:不能使用@PreAuthorize方法安全【英文标题】:spring boot (1.3) based oauth2 resource server: Can not use @PreAuthorize method security 【发布时间】:2016-07-01 04:57:43 【问题描述】:

我们已经运行了一个 Oauth 授权服务器,现在我正在尝试创建一个基于 spring boot 1.3 的非常简单的资源服务器,并使用 oauth2 访问令牌进行保护。它工作正常,并且可以使用有效的 oauth2 访问令牌访问资源。 但是现在我想检查一个 oauth 范围,所以我在方法之前添加了注释 @PreAuthorize 但它抛出了一个异常并且应用程序无法启动:

org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built

这里是资源类:

@SpringBootApplication
@RestController
@EnableResourceServer
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)

public class ResourceServerApplication 

@PreAuthorize("#oauth2.hasScope('READ')")
@RequestMapping(method = RequestMethod.GET, value = "/username")
public String user(OAuth2Authentication auth) 
    return auth.getName();


public static void main(String[] args) 
    SpringApplication.run(ResourceServerApplication.class, args);



这就是我的 POM 的样子:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Brixton.M5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
    </dependency>

    <!--  
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    -->
</dependencies>

异常跟踪:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceServerApplication': Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; 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]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.aopalliance.intercept.MethodInterceptor]: Factory method 'methodSecurityInterceptor' 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:599) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:199) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4659) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5281) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_65]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_65]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_65]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_65]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to     instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceServerApplication': Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; 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]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.aopalliance.intercept.MethodInterceptor]: Factory method 'methodSecurityInterceptor' 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:189) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 23 common frames omitted

如果我只是注释掉行 '@PreAuthorize("#oauth2.hasScope('READ')")',应用程序可以正常启动

我只想在这里使用 oauth2 的 prePost 方法安全性。谁能帮帮我?

【问题讨论】:

【参考方案1】:

通过将所有注释放入单个应用程序类中,我遇到了类似的问题。

创建一个这样的类

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableResourceServer
class ResourceAppConfig 

并从您的主应用程序类中删除这些注释。

最好的问候

【讨论】:

谢谢大卫。我试过你的建议,但没有帮助。仍然遇到同样的问题。【参考方案2】:

去掉@EnableAutoConfiguration 跟那个有冲突

【讨论】:

以上是关于spring boot(1.3)基于oauth2资源服务器:不能使用@PreAuthorize方法安全的主要内容,如果未能解决你的问题,请参考以下文章

thymeltesys-基于Spring Boot Oauth2的扫码登录框架

单个 Spring Boot 应用程序中的 SAML 和 Oauth2

在 Spring Boot 2 上实现基于过滤器的 JWT 身份验证与 OAuth2 JWT 身份验证

Spring Security OAuth2.0认证授权

Spring Security OAuth2.0认证授权

Spring Security OAuth2.0认证授权