Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的代币被拒绝?什么是资源ID&引用;无效令牌不包含资源id(oauth2资源)";_Java_Spring_Oauth 2.0_Jwt_Spring Security Oauth2 - Fatal编程技术网

Java 为什么我的代币被拒绝?什么是资源ID&引用;无效令牌不包含资源id(oauth2资源)";

Java 为什么我的代币被拒绝?什么是资源ID&引用;无效令牌不包含资源id(oauth2资源)";,java,spring,oauth-2.0,jwt,spring-security-oauth2,Java,Spring,Oauth 2.0,Jwt,Spring Security Oauth2,我正在尝试为spring项目配置OAuth2。我正在使用我的工作场所提供的一个共享UAA()实例(因此我不尝试创建授权服务器,授权服务器与资源服务器是分开的)。前端是一个单页应用程序,它使用隐式授权直接从授权服务器获取令牌。我有SPA设置,它在每个web API调用的微服务上添加Authorization:Bearer头 我现在的问题是微服务 我正在尝试使用这个共享授权服务器来验证微服务。我可能有一个误解,我目前的理解是,这些微服务扮演着资源服务器的角色,因为它们承载SPA用来获取数据的端点 所

我正在尝试为spring项目配置OAuth2。我正在使用我的工作场所提供的一个共享UAA()实例(因此我不尝试创建授权服务器,授权服务器与资源服务器是分开的)。前端是一个单页应用程序,它使用隐式授权直接从授权服务器获取令牌。我有SPA设置,它在每个web API调用的微服务上添加
Authorization:Bearer

我现在的问题是微服务

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

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

@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());
    }
}

下面是我的问题:
  • 我如何配置这些微服务来验证令牌并在控制器方法中插入一个?我目前在SPA拥有并发送令牌的位置进行了设置,我还拥有用于验证令牌签名的公钥。我也曾经测试过这个令牌,上面写着“签名已验证”
  • 什么是资源id?为什么我需要它,为什么它会导致上述错误?那是弹簧唯一的东西吗
谢谢

Spring OAuth期望JWT令牌中有“aud”。该声明的值应该与您指定的Spring应用程序的
resourceId
值匹配(如果未指定,则默认为“oauth2资源”)

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

1) 登录您的共享UAA,确保它包含“aud”索赔

2) 将“aud”声明的值更改为“oauth2资源”,或者最好在Spring应用程序更新
resourceId
中将其更改为该声明的值,如下所示:

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

我补充一个类似的问题。在我的例子中,我使用jdbc身份验证,我的授权服务器和资源服务器是两个独立的API

  • 授权服务器

       @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
    oauthServer.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .passwordEncoder(oauthClientPasswordEncoder);
    
    }

  • 资源服务器

    public class OAuth2ResourceServerConfig extends 
        ResourceServerConfigurerAdapter {
    
        private TokenExtractor tokenExtractor = new BearerTokenExtractor();
    
        @Autowired
        private DataSource dataSource;
    
        @Bean
        public TokenStore tokenStore() {
          return new JdbcTokenStore(dataSource);
        }
    
         @Override
         public void configure(HttpSecurity http) throws Exception {
               http.addFilterAfter(new OncePerRequestFilter() {
               @Override
               protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                FilterChain filterChain) throws ServletException, IOException {
            // We don't want to allow access to a resource with no token so clear
            // the security context in case it is actually an OAuth2Authentication
            if (tokenExtractor.extract(request) == null) {
                SecurityContextHolder.clearContext();
            }
            filterChain.doFilter(request, response);
        }
    }, AbstractPreAuthenticatedProcessingFilter.class);
    http.csrf().disable();
    http.authorizeRequests().anyRequest().authenticated();
     }
    
      @Bean
      public AccessTokenConverter accessTokenConverter() {
         return new DefaultAccessTokenConverter();
      }
    
      @Bean
      public RemoteTokenServices remoteTokenServices(final @Value("${auth.server.url}") String checkTokenUrl,
        final @Value("${auth.resource.server.clientId}") String clientId,
        final @Value("${auth.resource.server.clientsecret}") String clientSecret) {
    
           final RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
           remoteTokenServices.setCheckTokenEndpointUrl(checkTokenUrl);
           remoteTokenServices.setClientId(clientId);
           remoteTokenServices.setClientSecret(clientSecret);
          remoteTokenServices.setAccessTokenConverter(accessTokenConverter());
    return remoteTokenServices;
       }
    
通过这种配置,我得到了

    {
       "error": "access_denied",
       "error_description": "Invalid token does not contain resource id 
       (xxxxx)"
     }
为了解决这个问题,我必须添加

    private String resourceIds= "xxxxx". !! maked sure that this resourceids is store in oauth_client_details for the clientid I used to get the token
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
          resources.resourceId(resourceIds).tokenStore(tokenStore());
      }

我在用spring实现oauth2.0时遇到了同样的问题,下面是我对resourceid的发现

Spring Security OAuth2体系结构分为授权服务器和资源服务器资源服务器。我们可以为每个资源服务器(一个微服务实例)设置一个ResourceID。当授权服务器向客户端授予授权时,您可以设置客户端可以访问哪些资源服务器资源服务

在授权服务器中为客户端配置ResourceID的目的是限制客户端可以访问的资源服务

要设置ResourceID,请参考下面的链接,

注意:在授权服务器上使用KeyClope时,resourceId应设置为客户端id。非常感谢您的回答!!!!!!!上面的评论就是这个问题的答案。这个答案没有回答第二个问题
什么是资源id?为什么我需要它,为什么它会导致上述错误?这是弹簧唯一的东西吗???
。我找不到有关术语
资源id
的任何信息。我不知道为什么我需要这个,我的客户端(前端SPA)只发送访问令牌(不是JWT,只是简单的随机文本)。它对我有效,我只需要确保aud值(oauth_client_details表的resource_id值)必须与resources.resourceId(这里的值_)匹配。这对我不起作用。我的代码中已经有resources.resourceId调用,但不起作用。谢谢,我面临相同的问题如何使用承载令牌将其添加到请求中,我仍然面临相同的问题,我已经添加了此配置。
    {
       "error": "access_denied",
       "error_description": "Invalid token does not contain resource id 
       (xxxxx)"
     }
    private String resourceIds= "xxxxx". !! maked sure that this resourceids is store in oauth_client_details for the clientid I used to get the token
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
          resources.resourceId(resourceIds).tokenStore(tokenStore());
      }