spring boot oauth2 ResourceServerConfigurerAdapter 不保护资源

Posted

技术标签:

【中文标题】spring boot oauth2 ResourceServerConfigurerAdapter 不保护资源【英文标题】:spring boot oauth2 ResourceServerConfigurerAdapter not protecting resources 【发布时间】:2020-11-30 19:59:56 【问题描述】:

/oauth/token 工作正常。

资源服务器中的.antMatchers("/api/waiter/**") 可供公众访问。

.antMatchers("/api/waiter/").hasAnyRole(RESTRWAITER).antMatchers("/api/waiter/").authenticated()

我已经明确定义了 api 的角色。

资源服务器配置似乎有问题。

我的代码是

@Configuration
@EnableResourceServer
@Order(2)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter 

@Value("$spring.datasource.driver-class-name")
private String oauthClass;

@Value("$spring.datasource.url")
private String oauthUrl;

@Value("$spring.datasource.username")
private String username;

@Value("$spring.datasource.password")
private String password;

private static final String RESTRWAITER = "WAITER";

@Bean
public TokenStore tokenStore() 
    DataSource tokenDataSource = DataSourceBuilder.create().driverClassName(oauthClass).username(username)
            .password(password).url(oauthUrl).build();
    return new JdbcTokenStore(tokenDataSource);


@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception 
    resources.resourceId("scout").tokenStore(tokenStore());


@Override
public void configure(HttpSecurity http) throws Exception 
    http.anonymous().disable().requestMatchers().antMatchers("/api/waiter/**").and().authorizeRequests()
            .antMatchers("/api/waiter/**").hasAnyRole(RESTRWAITER).antMatchers("/api/waiter/**").authenticated().and().exceptionHandling()
            .accessDeniedHandler(new OAuth2AccessDeniedHandler());


授权服务器配置

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter 

@Autowired
private AuthenticationManager authenticationManager;

@Value("$spring.datasource.driver-class-name")
private String oauthClass;

@Value("$spring.datasource.url")
private String oauthUrl;

@Value("$spring.datasource.username")
private String username;

@Value("$spring.datasource.password")
private String password;

@Bean
public TokenStore tokenStore() 
    System.out.println(username);
    DataSource tokenDataSource = DataSourceBuilder.create().driverClassName(oauthClass).username(username)
            .password(password).url(oauthUrl).build();
    return new JdbcTokenStore(tokenDataSource);


@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
    endpoints.authenticationManager(authenticationManager);
    endpoints.tokenStore(tokenStore());


@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception 
    security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
            .allowFormAuthenticationForClients();


@Bean
public PasswordEncoder getPasswordEncoder() 
    return new BCryptPasswordEncoder();


@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
    clients.inMemory().withClient("clientapp").secret(getPasswordEncoder().encode("123456"))
            .authorizedGrantTypes("password", "authorization_code", "refresh_token").authorities("READ_ONLY_CLIENT")
            .scopes("read_profile_info").resourceIds("oauth2-resource").redirectUris("http://localhost:8081/login")
            .accessTokenValiditySeconds(120000).refreshTokenValiditySeconds(240000);

安全配置

@Configuration
@EnableWebSecurity
@Order(1)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

private static final String SYSTEM = "SYSTEM";
private static final String RESTRUSER = "RESTRO";
private static final String RESTRWAITER = "WAITER";

@Autowired
private UserDetailsService userDetailsService;

@Autowired
private DataSource dataSource;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());



@Bean
public AuthenticationFailureHandler customAuthenticationFailureHandler() 
    return new CustomAuthenticationFailureHandler();


@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception 
    return super.authenticationManagerBean();


 @Override
    public void configure(WebSecurity web) throws Exception 

        web
            .ignoring()
            .antMatchers("/api/waiter/**");

    

@Override
protected void configure(HttpSecurity http) throws Exception 
    http.authorizeRequests().antMatchers("/admin/**").hasRole(SYSTEM).antMatchers("/restro/**")
            .hasAnyRole(RESTRUSER).antMatchers("/waiter/**").hasAnyRole(RESTRWAITER).antMatchers("/", "/pub/**")
            .permitAll().and().formLogin().loginPage("/login").defaultSuccessUrl("/dashboard")
            .failureHandler(customAuthenticationFailureHandler()).permitAll().and().logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/?logout")
            .deleteCookies("my-remember-me-cookie").permitAll().and().rememberMe()
            // .key("my-secure-key")
            .rememberMeCookieName("my-remember-me-cookie").tokenRepository(persistentTokenRepository())
            .tokenValiditySeconds(24 * 60 * 60).and().exceptionHandling();


PersistentTokenRepository persistentTokenRepository() 
    JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
    tokenRepositoryImpl.setDataSource(dataSource);
    return tokenRepositoryImpl;


@Bean
public PasswordEncoder getPasswordEncoder() 
    return new BCryptPasswordEncoder();

问题是资源服务器 .antMatchers("/api/waiter/**") 可以在没有 access_token 的情况下访问。 资源服务器配置不工作。

【问题讨论】:

【参考方案1】:

找到解决办法

刚刚在 SecurityConfiguration 上将 @Order(1) 替换为 @Order(SecurityProperties.BASIC_AUTH_ORDER) 。它奏效了。

@Configuration
@EnableWebSecurity
@Order(SecurityProperties.BASIC_AUTH_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

【讨论】:

以上是关于spring boot oauth2 ResourceServerConfigurerAdapter 不保护资源的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.0.0 + OAuth2

Spring Boot 和 OAuth2 社交登录,无法获取 refreshToken

使用 spring-boot OAuth2 服务器保护的 Spring-boot 应用程序

让 oauth2 与 spring-boot 和 rest 一起工作

Spring Boot Restful WebAPI集成 OAuth2

Spring Boot + Spring Security + Spring OAuth2 + Google 登录