【问题标题】:Spring JWT signature Validation failsSpring JWT 签名验证失败
【发布时间】:2018-04-30 10:47:40
【问题描述】:

我正在使用 Spring Cloud、oauth 和 JWT 构建微服务应用程序。我的 Oauth2 服务器生成 JWT 令牌,但是当我尝试验证网关中的令牌(使用 ZUUL 实现)时,我遇到了错误

能否请您告诉我出了什么问题以及可能的解决方案。 我使用的是 Spring 4.3、Spring boot 1.5.8、Spring cloud Dalston.SR4

org.springframework.security.jwt.crypto.sign.InvalidSignatureException: Calculated signature did not match actual value
    at org.springframework.security.jwt.crypto.sign.MacSigner.verify(MacSigner.java:62) ~[spring-security-jwt-1.0.8.RELEASE.jar:na]
    at org.springframework.security.jwt.JwtImpl.verifySignature(JwtHelper.java:287) ~[spring-security-jwt-1.0.8.RELEASE.jar:na]
    at org.springframework.security.jwt.JwtHelper.decodeAndVerify(JwtHelper.java:77) ~[spring-security-jwt-1.0.8.RELEASE.jar:na]
    at com.debopam.gateway.filter.CustomPostZuulFilter.run(CustomPostZuulFilter.java:57) ~[classes/:na]
    at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112) [zuul-core-1.3.0.jar:1.3.0]
    at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193) [zuul-core-1.3.0.jar:1.3.0]
    at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157) [zuul-core-1.3.0.jar:1.3.0]
    at com.netflix.zuul.FilterProcessor.postRoute(FilterProcessor.java:92) [zuul-core-1.3.0.jar:1.3.0]
    at com.netflix.zuul.ZuulRunner.postRoute(ZuulRunner.java:87) [zuul-core-1.3.0.jar:1.3.0]

我在身份验证服务器和网关服务器中都使用了签名密钥 12345AsDfG

下面是代码sn-p 身份验证服务器

@Configuration
public class JWTTokenStoreConfig {

    @Autowired
    private ServiceConfig serviceConfig;

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

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        defaultTokenServices.setAccessTokenValiditySeconds(60*30);
        return defaultTokenServices;
    }


    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(serviceConfig.getJwtSigningKey());
        return converter;
    }

    @Bean
    public TokenEnhancer jwtTokenEnhancer() {
        return new JWTTokenEnhancer();
    }
}


@Configuration
public class JWTOAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private DefaultTokenServices tokenServices;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private TokenEnhancer jwtTokenEnhancer;


    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception
    {
        //oauthServer.checkTokenAccess("permitAll()");    

        oauthServer
        .tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')")
        .checkTokenAccess("permitAll()");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer, jwtAccessTokenConverter));

        endpoints.tokenStore(tokenStore)                             //JWT
                .accessTokenConverter(jwtAccessTokenConverter)       //JWT
                .tokenEnhancer(tokenEnhancerChain)                   //JWT
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);


    }



    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        clients.inMemory()
                .withClient("uiapp")
                .secret("secret")
                .authorizedGrantTypes("refresh_token", "password", "client_credentials")
                .scopes("webclient", "mobileclient");
    }
}

网关应用程序中,我使用下面的代码来验证令牌

@Override
public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    try {
        InputStream is = ctx.getResponseDataStream();
        String responseBody = IOUtils.toString(is);

        if (StringUtils.hasText(responseBody) 
                && responseBody.contains("access_token")) {
            Map<String, Object> responseMap = objectMapper.readValue(
                    responseBody, new TypeReference<Map<String, Object>>() {});
            String accesToken = responseMap.get("access_token").toString();

            Jwt jwt = JwtHelper.decodeAndVerify(accesToken, new MacSigner(serviceConfig.getJwtSigningKey()));

            System.out.println(jwt.getClaims());
            //System.out.println(jwt.getBody());

        }
        ctx.setResponseBody(responseBody);
    } catch (Exception e) {
        logger.error("Error occured in zuul post filter", e);
    }
    return null;
}

【问题讨论】:

  • 我查看了 spring oauth 中的其他实现和测试,但一无所获。我会调试它。到达时令牌的格式是否正确?和生产的一样吗?两端的key一样吗?
  • 抱歉,服务之间存在密钥不匹配。

标签: java spring spring-security jwt spring-oauth2


【解决方案1】:

服务之间存在签名密钥不匹配。

【讨论】:

    猜你喜欢
    • 2016-06-12
    • 2018-10-02
    • 2016-12-27
    • 2019-06-14
    • 2016-12-16
    • 2018-11-03
    • 2021-09-10
    • 2020-12-04
    • 1970-01-01
    相关资源
    最近更新 更多