Spring 到 Ping:如何配置 Spring Rest 服务以使用外部授权服务器 PingFederate

Spring to Ping: how to configure Spring Rest Service to use External Authorization Server PingFederate

有谁知道如何配置 Spring 休息服务以使用 PingFederate 作为外部授权服务器?

之前问过这个问题,不知为何关闭了。但这是我找到的答案。我基于使用 Google 作为外部授权服务器的演示。通常的演示的问题是它们都使用 Spring 授权服务器。这里是开始的地方 https://arnoldgalovics.com/google-oauth-with-spring-security-as-separated-resource-server/ 然后像这样修改 GoogleAccessTokenValidator(如下)。有问题,开火...

private HttpHeaders createHeaders(final String username, final String password){
       return new HttpHeaders() {{
             String auth = username + ":" + password;
             byte[] encodedAuth = Base64.encodeBase64( 
                auth.getBytes(Charset.forName("US-ASCII")) );
             String authHeader = "Basic " + new String( encodedAuth );
             set( "Authorization", authHeader );
          }};
    }

    
    @SuppressWarnings("unchecked")
    private Map<String, ?> getPingResponse(String accessToken) {
        
        //Ping speaks text/html
        List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof StringHttpMessageConverter) {
                StringHttpMessageConverter stringConverter = (StringHttpMessageConverter) converter;                
                stringConverter.setSupportedMediaTypes(ImmutableList.of(new MediaType("text", "html", StringHttpMessageConverter.DEFAULT_CHARSET)));
            }
        }       
        
        //URL
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(checkTokenUrl)
                .queryParam("grant_type", "urn:pingidentity.com:oauth2:grant_type:validate_bearer")
                .queryParam("token", accessToken);      
        String url =  builder.build().encode().toUri().toString();
        
        //Basic Auth (from Ping, OAuth Settings, Manage Clients
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(createHeaders("my-trusted-client", "secret"));
        
        //unused Spring exchange variables
        Map<String, String> variables = ImmutableMap.of("ping does not", "use this"); //token only in queryParam above
        
        //validation call to Ping
        Map map = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class, variables).getBody();        
        return (Map<String, Object>) map;
    }

我尝试使用 jose4j

        <dependency>
            <groupId>org.bitbucket.b_c</groupId>
            <artifactId>jose4j</artifactId>
            <version>0.7.6</version>
        </dependency>

现在,下面是验证 JWT 和获取声明的代码。

        String jwtToken = "<token>"
        HttpsJwks httpsJkws = new HttpsJwks("<Ping Server Public cert URL>");
        HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setRequireExpirationTime()
                .setAllowedClockSkewInSeconds(30)
                .setRequireSubject()
                .setExpectedIssuer("<Issuer URL>")
                .setExpectedAudience("<audience>")
                .setVerificationKeyResolver(httpsJwksKeyResolver)
                .setJwsAlgorithmConstraints(
                        AlgorithmConstraints.ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256)
                .build();
       
        try
        {
           
            JwtClaims jwtClaims = jwtConsumer.processToClaims(jwtToken);
          
        } catch (InvalidJwtException e) {
           
            System.out.println("Invalid JWT! " + e);
           
            if (e.hasExpired())
            {
                System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());
            }
           
            if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID))
            {
                System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());
            }
        } 

我们可以通过提取在 HTTP header 中接收到的 JWT 令牌,通过 SpringBoot 拦截器集成上述代码 header。