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

时间:2017-10-30 13:01:03

标签: spring-security oauth-2.0 pingfederate

有谁知道如何配置Spring Rest服务以将PingFederate用作外部授权服务器?

2 个答案:

答案 0 :(得分:1)

之前被问到这个问题,因为上帝知道为什么而关闭了。但这是我找到的答案。我的基础是使用Google作为外部授权服务器的演示。通常演示的问题是它们都使用Spring Authorization Server。这是开始的地方http://blog.arnoldgalovics.com/2017/02/05/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;
    }

答案 1 :(得分:0)

我尝试使用 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());
            }
        } 

我们可以通过SpringBoot拦截器通过提取HTTP头中收到的JWT令牌来集成上面的代码。