Spring OAuth:具有授权服务器后端的资源服务器

Spring OAuth: Resource Server with Authorization Server backend

我想开发两项独立的服务,一项用于业务,一项用于使用 Spring OAuth 2

的用户身份验证

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

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

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

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

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

但是,如果我用 @EnableOAuth2Sso for enabling the redirection to the OAuth service, it looses the capability of accessing the resources with an access token (same curl as above), it only returns a 302 to the login page http://localhost:8667/login

注释业务服务

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

那么创建资源服务器的正确方法是什么,该资源服务器将未验证的调用委托给 auth 服务器?

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

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

@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/

returns

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



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

returns

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



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

returns

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。该服务的根适用于所有客户端,因此它们可以发现登录关系,如果它们遵循此关系,它们将被重定向到授权服务器