【问题标题】:OAuth2 multiple keys, public key migration, Resource ServerOAuth2 多密钥、公钥迁移、资源服务器
【发布时间】:2017-10-18 17:50:34
【问题描述】:

我的系统:安全提供商基于私钥生成 JWT 令牌。私钥属于将过期的证书。

  1. 是否可以在资源服务器中设置多个公钥?

我想做一个滚动更新,所以在短时间内它必须支持旧公钥和新公钥。这是一个默认用例,因为证书过期了。?

  1. oauth/token_key 可以提供多个密钥还是只提供一个?

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        Resource resource = new ClassPathResource("public.txt");
        String publicKey = null;
        try {
            publicKey = IOUtils.toString(resource.getInputStream());
        } 
        catch (final IOException e) { throw new RuntimeException(e);
    }
        **converter.setVerifierKey(publicKey);**
        **converter.setVerifierKeys(publicKey1, publicKey2);?**
        return converter;
    }
    

http://www.baeldung.com/spring-security-oauth-jwt

谢谢

【问题讨论】:

标签: spring-oauth2


【解决方案1】:

这不是标准做法,Spring 的 jwt 框架不支持开箱即用的多个安全提供程序(或多个活动验证器密钥)。话虽如此,您希望做的事情在理论上是可能的。您将为AccessTokenConverter 建立一个类似于JwtAccessTokenConverter 的新实现,但像这样实现decode 方法:

protected Map<String, Object> decode(String token) {
    try {
        Jwt jwt = JwtHelper.decodeAndVerify(token, verifier1);
        String content = jwt.getClaims();
        Map<String, Object> map = objectMapper.parseMap(content);
        if (map.containsKey(EXP) && map.get(EXP) instanceof Integer) {
            Integer intValue = (Integer) map.get(EXP);
            map.put(EXP, new Long(intValue));
        }
        return map;
    }
    catch (Exception e) {
      //try the other verifier
      try {
        Jwt jwt = JwtHelper.decodeAndVerify(token, verifier2);
        String content = jwt.getClaims();
        Map<String, Object> map = objectMapper.parseMap(content);
        if (map.containsKey(EXP) && map.get(EXP) instanceof Integer) {
            Integer intValue = (Integer) map.get(EXP);
            map.put(EXP, new Long(intValue));
        }
        return map;
    }
    catch(InvalidTokenException te){
       throw te;
    }catch (Exception e) {

        throw new InvalidTokenException("Cannot convert access token to JSON", e);
    }
    }
}

基本上,上面的代码尝试验证第一个密钥,但如果抛出任何异常,它将尝试验证第二个密钥。

我还建议您覆盖到 tokenConverter 以通过诸如“。”之类的分隔符拆分提供的令牌。或者不在生成验证器密钥的哈希算法的编码字符集中的东西。然后在调用时你可以这样做:setVerifierKey("verifierKey1" + delimiter + "verifierKey2")

  • 注意:我没有测试过这段代码,只是一些想法:)

【讨论】:

    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2014-09-15
    • 1970-01-01
    • 2019-11-27
    • 2013-07-16
    • 1970-01-01
    相关资源
    最近更新 更多