EnableResourceServer 中断 oAuth2 授权服务器

Posted

技术标签:

【中文标题】EnableResourceServer 中断 oAuth2 授权服务器【英文标题】:EnableResourceServer breaks oAuth2 authorization server 【发布时间】:2017-11-15 20:42:52 【问题描述】:

我使用 Spring Boot 版本 1.5.2.RELEASE 实现了 oAuth2 授权服务器。授权服务器支持隐式流。使用登录表单 (http://localhost:8200/login) 下面的 WebSecurityConfig 效果很好。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private JpaUserDetailsService userDetailsService;

    @Bean
    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception 
    return userDetailsService;
    

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

    @Bean
    public AuthenticationProvider authenticationProvider() throws Exception 
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(userDetailsServiceBean());
    provider.setPasswordEncoder(passwordEncoder());
    return provider;
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
    return new ProviderManager(singletonList(authenticationProvider()));
    

    @Override
    public void configure(WebSecurity web) 
    web.ignoring()
            .antMatchers("/")
            .antMatchers("/docs/**")
            .antMatchers("/swagger/**")
            .antMatchers("/token/**")
            .antMatchers("/v2/*")
        .antMatchers(HttpMethod.OPTIONS, "/**");
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
    http
            .authorizeRequests().antMatchers("/login**").permitAll().anyRequest().authenticated().and()
            .formLogin().loginPage("/login").permitAll().and()
            .logout().permitAll();
    

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    

我希望资源服务器成为同一应用程序的一部分。目的是我需要一个 /me 端点,它将为我提供登录用户的详细信息和用于管理用户的端点。但是,当我在下面添加带有 EnableResourceServer 注释的 ResourceServerConfig 时,当我请求 http://localhost:8200/login 时,我开始收到错误“访问此资源需要完全身份验证”。

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter 

    public static final String RESOURCE_ID = "proclaim-auth";

    @Autowired
    private ResourceServerTokenServices tokenServices;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception 
    resources
            .resourceId(RESOURCE_ID)
            .tokenServices(tokenServices);
    

    @Override
    public void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests().antMatchers("/api/ **").authenticated();
    

我怀疑资源服务器安全链先于授权服务器安全链。我尝试使用注释 Order 来注释 WebSecurityConfig,但它没有解决我的问题:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    ...

我做错了什么?请指教。 提前致谢!

编辑 1 我将方法 configure(HttpSecurity http) 添加到 ResourceServerConfig 中,并将 WebSecurityConfig 上的 Order 注释的值更改为 -1。现在应用了 WebSecurityConfig 中定义的安全过滤器,而 ResourceServerConfig 中定义的安全过滤器被忽略了。因此,当我使用有效令牌调用 /me 端点时,我将被重定向到登录页面。

【问题讨论】:

【参考方案1】:

问题的原因是 ResourceServerConfig 类中的 http 安全配置错误。正确的配置如下:

@Override
public void configure(HttpSecurity http) throws Exception 
    http
            .requestMatchers().antMatchers("/api/**").and()
            .authorizeRequests().anyRequest().authenticated();

requestMatchers 将确保只有以“/api/”开头的路径上的请求才会被此安全链处理。所有其他请求都将传递到 WebSecurityConfig 类中定义的安全链。我在我的配置中遗漏了这个,所以所有请求都由 ResourceServerConfig 安全链处理,并且没有一个请求到达 WebSecurityConfig 安全链。

【讨论】:

感谢分享,遇到了同样的问题。

以上是关于EnableResourceServer 中断 oAuth2 授权服务器的主要内容,如果未能解决你的问题,请参考以下文章

春天禁用@EnableResourceServer

Spring security 的 @EnableWebSecurity 与 oauth 的 @EnableResourceServer

使用 @EnableResourceServer 支持 Spring Boot 反应式 (webflux)

@EnableResourceServer 不适用于 spring-webflux

@EnableOAuth2Sso 和 @EnableResourceServer 在同一个应用程序中

Spring OAuth @EnableResourceServer 阻止来自 OAuth 服务器的登录页面