为什么我的令牌被拒绝?什么是资源 ID?“无效令牌不包含资源 id (oauth2-resource)"

我正在尝试为 spring 项目配置 OAuth2.我正在使用共享 UAA(来自云代工厂的 oauth 实现)实例我的工作场所提供(所以我没有尝试创建授权服务器,并且授权服务器与资源服务器分开).前端是一个单页应用程序,它使用隐式授权直接从授权服务器获取令牌.我有 SPA 设置,它在每个对微服务的 Web API 调用上添加 Authorization: Bearer <TOKEN> 标头.

I'm trying to configure OAuth2 for a spring project. I'm using a shared UAA (oauth implementation from cloud foundry) instance my work place provides (so I'm not trying to create an authorization server and the authorization server is separate from the resource server). The frontend is a single-page-application and it gets token directly from the authorization server using the implicit grant. I have the SPA setup where it adds the Authorization: Bearer <TOKEN> header on each web API call to microservices.

我现在的问题是微服务.

My issue is now with the microservices.

我正在尝试使用此共享授权服务器来验证微服务.这里我可能有一个误解,买我目前的理解是这些微服务扮演资源服务器的角色,因为它们托管 SPA 用来获取数据的端点.

I'm trying to use this shared authorization server to authenticate the microservices. I might have a misunderstanding here, buy my current understanding is that these microservices play the role of the resource server because they host the endpoints the SPA uses to get data.

所以我尝试像这样配置一个微服务:

So I tried to configure a microservice like so:

@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

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

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setVerifierKey("-----BEGIN PUBLIC KEY-----<key omitted>-----END PUBLIC KEY-----");
        return converter;
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }


    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
         resources.tokenServices(tokenServices());
    }
}

现在,每当我使用 Authorization: Bearer <TOKEN> 访问 /api/** 时,我都会得到一个 403错误:

Now whenever I hit a /api/** with the Authorization: Bearer <TOKEN>, I get a 403 with this error:

{
    "error": "access_denied",
    "error_description": "Invalid token does not contain resource id (oauth2-resource)"
}

<小时>

所以这是我的问题:

  • 如何配置这些微服务以验证令牌并插入 Principal 在控制器方法中? 我目前已经在 SPA 拥有并发送令牌的地方设置了它,并且我还有用于验证令牌的签名.我还使用 jwt.io 来测试令牌并显示签名已验证".
  • 什么是资源 ID?为什么我需要它,为什么它会导致上述错误?那只是春天的事吗??

  • So here are my questions:

    • How do I configure these microservices to validate the token and insert a Principal in controller methods? I currently have it setup where the SPA has and sends the token and I also have the public key used to verify the signature of the token. I have also used jwt.io to test the token and it says "Signature Verified".
    • What is a resource id? Why do I need it and why does it cause the error above? Is that a Spring only thing??
    • 谢谢!

      推荐答案

      Spring OAuth 需要aud" 声明.该声明的值应与您指定 Spring 应用程序的 resourceId 值匹配(如果未指定,则默认为oauth2-resource").

      Spring OAuth expects "aud" claim in JWT token. That claim's value should match to the resourceId value you specify your Spring app (if not specified it defaults to "oauth2-resource").

      要解决您的问题,您需要:

      To fix your issue you need to:

      1) 登录您的共享 UAA 并确保其中包含aud"声明.

      1) Log into your shared UAA and make sure it does include "aud" claim.

      2) 将该aud"声明的值更改为oauth2-resource",或者最好在您的 Spring 应用程序中将 resourceId 更改为该声明的值,如下所示:

      2) Change the value of that "aud" claim to be "oauth2-resource" or preferably in your Spring app update resourceId to that claim's value like this:

          @Override
          public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
               resources.tokenServices(tokenServices());
               resources.resourceId(value from the aud claim you got from UAA server);
          }
      

相关文章