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

Md *_*aza 5 spring spring-security spring-boot 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.
    }

}
Run Code Online (Sandbox Code Playgroud)
@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;
    }
Run Code Online (Sandbox Code Playgroud)

}

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)
@Configuration
@EnableGlobalMethodSecurity
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new OAuth2MethodSecurityExpressionHandler();
    }
}
Run Code Online (Sandbox Code Playgroud)
@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();
    }
Run Code Online (Sandbox Code Playgroud)

}

<?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>
Run Code Online (Sandbox Code Playgroud)

我错过了什么?感谢帮助.

更新: 我发现由于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");
    }

}
Run Code Online (Sandbox Code Playgroud)

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

Md *_*aza 7

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

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

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

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