Search code examples
spring-securityoauth-2.0pingfederate

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


Does anyone know how to configure a Spring Rest Service to use PingFederate as an External Authorization Server?


Solution

  • Asked this question before, it was closed for god knows why. But here is the answer that I found. I based this on a demo that uses Google as an external authorization server. The problem with the usual demos is that they all use the Spring Authorization Server. Here is the place to start https://arnoldgalovics.com/google-oauth-with-spring-security-as-separated-resource-server/ Then modify the GoogleAccessTokenValidator like this (below). Questions, fire away...

    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;
        }