spring boot oauth2配置:资源服务器保持不受保护

时间:2017-03-09 20:15:38

标签: spring spring-boot spring-security spring-security-oauth2

我使用spring boot实现了授权服务器和资源服务器。授权服务器工作正常,我能得到令牌。但我的资源服务器仍然没有受到保护。我的目标是资源服务器只能由具有有效访问令牌的人访问。

我的整个代码是:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    TokenStore tokenStore;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints
            .tokenStore(tokenStore)
            .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
            .inMemory()
            .withClient("client")
            .scopes("read", "write")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .authorizedGrantTypes("password", "refresh_token")
            .secret("secret")
            .accessTokenValiditySeconds(180)
            .refreshTokenValiditySeconds(600);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        super.configure(security); //To change body of generated methods, choose Tools | Templates.
    }

}
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources
                .tokenServices(tokenServices())
                .resourceId("MY_RESOURCE");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .anonymous().disable()
                .requestMatchers().antMatchers("/**")
            .and()
                .authorizeRequests()
                    .antMatchers("/").access("hasRole('USER')")
                    .antMatchers("/secure/").access("hasRole('ADMIN')")
            .and()
                .exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore);
        return defaultTokenServices;
    }

}

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("bill").password("abc123").roles("ADMIN").and()
        .withUser("bob").password("abc123").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .anonymous().disable()
                .authorizeRequests()
                    .antMatchers("/oauth/token").permitAll();
    }
}
@Configuration
@EnableGlobalMethodSecurity
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new OAuth2MethodSecurityExpressionHandler();
    }
}
@SpringBootApplication
@RestController
public class Application extends SpringBootServletInitializer{

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @GetMapping(value = "/")
    public ResponseEntity<?> hello(){
        return ResponseEntity.ok("Hello World");
    }

    @GetMapping(value = "/secure/")
    public ResponseEntity<?> secure(){
        return ResponseEntity.ok("Secure Resorce");
    }
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>boot-oauth2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>boot-oauth2</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>


    <dependencies>
        <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.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins> 
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>
</project>

我错过了什么? 谢谢你的帮助。

更新 我发现由于OAuth2SecurityConfig类的存在,我的资源服务器没有受到保护。如果我删除此类并添加以下类(我已移动inMemmory用户),则资源服务器将根据需要受到保护

@Configuration
public class WebSecurityGlobalConfig extends GlobalAuthenticationConfigurerAdapter {

    @Autowired
    UserService userService;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("bill").password("abc123").roles("ADMIN").and()
        .withUser("bob").password("abc123").roles("USER");
    }

}

因此,我感觉OAuth2SecurityConfig类中的不正确HttpSecurity配置与资源服务器配置冲突。 那么,我如何配置OAuth2SecurityConfig的HttpSecurity,它确实允许资源服务器路径的访问令牌保护和非资源服务器路径的正常Web安全

3 个答案:

答案 0 :(得分:7)

经过大量的谷歌搜索后,我找到了解决方案。

这是由于过滤器的顺序。在spring-boot-1.5.1中更改了OAuth2资源过滤器的顺序。如更改日志所示

  

OAuth2资源过滤器的默认顺序已从3更改为   SecurityProperties.ACCESS_OVERRIDE_ORDER - 1.这将它置于之后   执行器端点但在基本认证过滤器链之前。   可以通过设置恢复默认值   security.oauth2.resource.filter-order = 3

因此,我通过在application.properties security.oauth2.resource.filter-order = 3中设置将我的OAuth2资源服务器过滤器的顺序更改为3,我的问题就解决了。

答案 1 :(得分:0)

使用@EnableGlobalMethodSecurity(prePostEnabled = true)注释您的OAuth2SecurityConfig

答案 2 :(得分:0)

我遇到了同样的问题。

我有另一个扩展WebSecurityConfigurerAdapter的类,我认为它与AuthorizationServerConfigurerAdapter冲突。

我只是删除了WebSecurityConfigurerAdapter 类,但它确实有效。