Spring Boot OAuth2配置:资源服务器仍然没有受保护。

6
我已经使用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类的存在。如果我删除这个类并添加以下类(我已经将内存用户移动到其中),那么资源服务器就像所需的那样受到保护。

@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安全性。


一切都在同一个应用程序中还是分开的? - sura2k
所有功能都在一个应用程序中。 - Md Zahid Raza
3个回答

8

经过大量的搜索,我终于找到了解决方法。

问题出在过滤器的顺序上。在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,问题得到了解决。


谢谢,这节省了我很多时间! - xiaofeng.li
这个属性在Boot 2.x中已被移除。有什么解决方案吗? - Rites

0
在您的OAuth2SecurityConfig中使用@EnableGlobalMethodSecurity(prePostEnabled = true)进行注解。

0

我曾经遇到过同样的问题。

我的另一个类继承了WebSecurityConfigurerAdapter,我猜想它与AuthorizationServerConfigurerAdapter有冲突。

我只是移除了WebSecurityConfigurerAdapter类,然后它就可以工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接