【问题标题】:Spring OAuth: Resource Server with Authorization Server backendSpring OAuth:带有授权服务器后端的资源服务器
【发布时间】:2015-05-14 20:44:47
【问题描述】:

我想开发两个独立的服务,一个用于业务的东西,一个用于使用 Spring OAuth 2 的用户身份验证

我们称它们为 Business-Service 和 OAuth-Service。

现在,如果请求未通过身份验证,我希望将业务服务委托给 OAuth 服务。客户端应用程序(Android 应用程序)不应该先验地知道 OAuth-Service,它应该只由 Business-Service 委托给它,并针对未经过身份验证的请求使用 302 HTTP 重定向。准确地说,我希望我的 API 登录页面提供一个指向 http://businessservice.com/login 的链接,当我的客户端应用决定使用此链接时,它会被重定向到 OAuth 服务。

如果我用 @EnableOAuth2Resource 注释业务服务,则当我在没有访问令牌的情况下卷曲它们时,它的所有资源都会受到保护,返回 401。到目前为止,一切都很好。如果我提供这样的访问令牌:

curl -v http://localhost:8667/resource/ -H "Authorization: Bearer $TOKEN"

我可以访问该资源。还是不错的。

但是,如果我使用 @EnableOAuth2Sso 注释业务服务以启用到 OAuth 服务的重定向,它会失去使用访问令牌访问资源的能力(与上面相同的 curl),它只会返回 302 到登录页面http://localhost:8667/login

如果我同时使用这两个注释,@EnableOAuth2Resource 似乎总是“获胜”,因为身份验证有效,但调用 http://localhost:8667/login 返回 404。

那么,创建一个资源服务器并委托给身份验证服务器进行非身份验证调用的正确方法是什么?

【问题讨论】:

    标签: spring-security oauth-2.0 spring-security-oauth2 spring-cloud


    【解决方案1】:

    经过几个小时的尝试,我现在找到了解决方案。

    业务服务器(资源服务器)现在如下所示:

    @SpringBootApplication
    @EnableOAuth2Sso
    @EnableOAuth2Resource
    public class BusinessService {
    
        public static void main(final String[] args) {
            final ConfigurableApplicationContext context = SpringApplication.run(BusinessService.class, args);
        }
    
    }
    

    有两种配置,一种用于 SSO:

    @Configuration
    public class OAuth2SsoConfiguration extends OAuth2SsoConfigurerAdapter {
    
        @Override
        public void match(final RequestMatchers matchers) {
            matchers.antMatchers("/");
        }
    
        @Override
        public void configure(final HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().permitAll();
        }
    
    }
    

    一个用于资源:

    @Configuration
    public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(final HttpSecurity http) throws Exception {
            http.requestMatchers().antMatchers("/resource/**").and().authorizeRequests().anyRequest().authenticated().antMatchers("/").permitAll();
    
        }
    
    }
    



    结果如下:

    curl -v http://localhost:8667/
    

    返回

    HTTP/1.1 200 OK
    {"links":[{"rel":"login","href":"http://localhost:8667/login"}]}
    



    curl -v http://localhost:8667/resource/
    

    返回

    HTTP/1.1 401 Unauthorized
    {"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
    



    curl -v http://localhost:8667/login
    

    返回

    HTTP/1.1 302 Found
    Location: http://localhost:8666/user/oauth/authorize?client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A8667%2Flogin&response_type=code&state=YmmNO9
    

    因此,我的业务服务作为资源服务器受到保护,资源服务器为所有业务资源返回 401。该服务的根适用于所有客户端,因此他们可以发现登录关系,如果他们遵循这种关系,他们将被重定向到授权服务器

    【讨论】:

    • 能否分享一下用户通过oauth2认证后如何在资源服务器中获取用户信息?
    • @Kane,为时已晚,但可能对其他人有所帮助。您可以在端点中使用以下参数:@RequestHeader(value = "Authorization") String authorizationHeader, Principal currentUser
    猜你喜欢
    • 2019-04-05
    • 2022-11-23
    • 2018-05-09
    • 2018-05-07
    • 2013-04-20
    • 2018-08-29
    • 2016-05-21
    • 2014-07-09
    • 2015-05-14
    相关资源
    最近更新 更多