在同一上下文中使用 Spring Boot 2 OAuth Client 和 Resourcesserver

Posted

技术标签:

【中文标题】在同一上下文中使用 Spring Boot 2 OAuth Client 和 Resourcesserver【英文标题】:Using Spring Boot 2 OAuth Client and Resourceserver in the same context 【发布时间】:2020-03-07 08:34:36 【问题描述】:

我希望我的 Spring Boot 应用程序服务于受保护的前端,同时作为所述前端的 API 资源服务器,但我无法让 oauth 工作。

我想要的是当浏览器在没有令牌的情况下请求 index.html 时,spring boot 应用程序将 302 重定向返回到 oauth 服务器(在我的情况下为 gitlab),因此用户被发送到登录表单。但我也希望 API 在没有令牌的情况下调用 API 时返回 401,因为我认为 302 重定向到登录页面在那里不是很有用。

在伪代码中:

if document_url == /index.html and token not valid
  return 302 https//gitlab/loginpage
if document_url == /api/restcall and token not valid
  return 401
server document_url

我正在使用 spring boot 2.1,关于我的 pom.xml 包含的 oauth

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>

这是我在 SecurityConfig 中的幼稚尝试

public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .authorizeRequests().antMatchers("/index.html").authenticated()
        .and()
            .oauth2Login().loginPage("/oauth2/authorization/gitlab")

        .and()
            .authorizeRequests().antMatchers("/api/restcall").authenticated()
        .and()
            .oauth2ResourceServer().jwt();
    

两种配置(oauth2Login 和 oauth2ResourceServer)都可以正常工作。但是一旦我将它们组合在一起,最后一个就赢了(所以在上面的例子中没有 302 并且浏览器也会看到 index.html 的 401)。我认为他们共享一些配置对象,所以最后一次写入获胜。

有没有一种(简单的)方法可以得到我想要的东西?我知道 spring 几乎可以做任何事情,但我非常不想最终手动配置大量 bean ...

更新:

我为我的代码here做了一个最小的例子(包括@dur的建议)

【问题讨论】:

你尝试了多种配置吗? 你的意思是把我的定义分成两个类SecurityConfig1和SecurityConfig2?是的,那也没用。根据加载顺序,其中一个仍然获胜。 是的,我就是这个意思。它应该工作。您必须为另一个 URL 模式限制您的配置。 【参考方案1】:

您需要创建多个配置,并使用requestMatcher 将它们仅限于特定的 URL 模式。根据您的示例,您的配置应如下所示:

SecurityConfigHTML

public class SecurityConfigHTML extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .requestMatchers().antMatchers("/index.html")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2Login().loginPage("/oauth2/authorization/gitlab");
    

SecurityConfigAPI

public class SecurityConfigAPI extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .requestMatchers().antMatchers("/api/call")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2ResourceServer().jwt();
    

【讨论】:

谢谢!奇迹般有效。我想补充一点,这里记录了这一点:docs.spring.io/spring-security/site/docs/current/reference/html/…

以上是关于在同一上下文中使用 Spring Boot 2 OAuth Client 和 Resourcesserver的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 上下文中的 Jooq CastException 已刷新

Spring Boot在servlet上下文之外获取应用程序基本url

Spring boot 2 WebClient在订阅者中获取上下文参数

如何调试,为啥 Spring Boot 集成测试上下文没有在测试之间重用?

在 spring-boot 项目中使用 spring mvc xml 项目

使用上下文路径的 POST 调用在 Spring Boot 2.x 中不起作用