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 和 OAuth2 社交登录,无法获取 refreshToken
使用 spring-boot OAuth2 服务器保护的 Spring-boot 应用程序
让 oauth2 与 spring-boot 和 rest 一起工作