2016-08-09 30 views
0

KeyCloakで保護されたアプリケーションのREST APIを消費する必要があります。これは、ブローカからOAUTH2プロバイダへの役割を果たします。OAUTH2プロバイダのブローカとしてKeycloakでREST APIを使用する

この目的のために、私はOAuth2RestTemplateとResourceOwnerPasswordDetailsを使用します。 第三者プロバイダから問題なくアクセストークンを取得できますが、それをどのように利用すればよいのでしょうか。ベアラとしてヘッダーでそれを使用することは役に立ちません。

提案がありますか?アクセストークン

@Autowired 
private OAuthConfig authConfig; 

@Override 
public OAuth2AccessToken getAccessToken(){ 
ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider(); 
OAuth2AccessToken accessToken = provider.obtainAccessToken(authConfig.resource(), new DefaultAccessTokenRequest()); 
return accessToken; 
} 

エラーは私が手OAuth2RestTemplate

@Autowired private ProdAuthService authService; 

OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(authConfig.resource(), new DefaultOAuth2ClientContext(authService.getAccessToken())); 
restTemplate.setRequestFactory(requestFactory); 
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 
restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); 
HttpHeaders header = new HttpHeaders(); 
header.setContentType(MediaType.APPLICATION_JSON); 
header.set("Authorization", "Bearer " + authService.getAccessToken()); 
HttpEntity<String> request = new HttpEntity<String>(header); 
ResponseEntity <ProcessInstanceLogWrapper> response = restTemplate.exchange(uri, HttpMethod.GET, request, new ParameterizedTypeReference<ProcessInstanceLogWrapper>(){}); 
ProcessInstanceLogWrapper json = response.getBody(); 

Caused by: org.springframework.security.oauth2.client.http.AccessTokenRequiredException: OAuth2 access denied. 
を得る

OAuthConfig.java

@Bean 
public ResourceOwnerPasswordResourceDetails resource(){ 
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails(); 
resource.setClientAuthenticationScheme(AuthenticationScheme.form); 
resource.setAccessTokenUri(env.getProperty("access.token.uri")); 
resource.setClientId(env.getProperty("access.client.id")); 
resource.setGrantType("password"); 
resource.setClientSecret(env.getProperty("access.client.secret")); 
resource.setUsername(env.getProperty("access.client.username")); 
resource.setPassword(env.getProperty("access.client.password")); 
resource.setScope(Arrays.asList(env.getProperty("access.client.scope"))); 
return resource; 
} 

サービス

KeycloakではAuthorizaion URLも使用していますが、ResourceOwnerPasswordResourceDetailsで使用することはできないようです。それはまた、私の意見によると、それは動作しません。

+0

これはうまく動作しますか? – Dineshmohan

+0

途中で...少なくとも、私はこの問題を解決していませんでした。あなたが同じ問題を抱えているなら、最も速いが、残念なことに安全な解決策ではなく、基本認証を使用してそれを使用することができます...私はそうしました... – user3467471

+0

私はそれを稼働させることができました。明日、コードを共有します。 – Dineshmohan

答えて

1

RestTemplate作成:

protected RestKeyCloakClient() 
{ 
    MultiValueMap<String, String> header = new LinkedMultiValueMap<String, String>(); 
    OAuth2RestTemplate client; 
    DefaultAccessTokenRequest accessTokenRequest = new DefaultAccessTokenRequest(); 
    DefaultOAuth2ClientContext context = new DefaultOAuth2ClientContext(accessTokenRequest); 
    OAuth2AccessTokenSupport support = new OAuth2AccessTokenSupport() 
    { 
    }; 
    List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>(); 
    messageConverters.add(new FormOAuth2AccessTokenMessageConverter()); 
    messageConverters.add(new FormOAuth2ExceptionHttpMessageConverter()); 
    MappingJackson2HttpMessageConverter jackson = new MappingJackson2HttpMessageConverter(); 
    List<MediaType> mediaTypes = new ArrayList<MediaType>(); 
    mediaTypes.add(new MediaType("application", "x-www-form-urlencoded")); 
    jackson.setSupportedMediaTypes(mediaTypes); 
    messageConverters.add(jackson); 
    support.setMessageConverters(messageConverters); 
    client = new OAuth2RestTemplate(getAuthDetails(null, null), context); 
    client.setErrorHandler(errorHandler); 
    client.setRequestFactory(factory); 
    token = client.getAccessToken(); 
} 

ResourceOwnerPasswordResourceDetails:

private ResourceOwnerPasswordResourceDetails getAuthDetails(String userName, String userPwd) 
{ 

    TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() 
    { 
     @Override 
     public java.security.cert.X509Certificate[] getAcceptedIssuers() 
     { 
      return null; 
     } 

     @Override 
     public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) 
     { 
     } 

     @Override 
     public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) 
     { 
     } 
    }}; 

    try { 
     SSLContext sc = SSLContext.getInstance("SSL"); 
     sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
    } catch (Exception e) { 
    } 

    ResourceOwnerPasswordResourceDetails authDetails = new ResourceOwnerPasswordResourceDetails(); 
    authDetails.setAccessTokenUri(LoggerAndReader.getInstance().getoAuth2tokenRequestUrl()); 
    authDetails.setClientId(LoggerAndReader.getInstance().getoAuth2ClientId()); 
    authDetails.setClientSecret(LoggerAndReader.getInstance().getoAuth2SecretToken()); 
    authDetails.setGrantType(LoggerAndReader.getInstance().getOauth2granttype()); 
    if (StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(userPwd)) { 
     authDetails.setUsername(userName); 
     authDetails.setPassword(userPwd); 
    } else { 
     authDetails.setUsername(LoggerAndReader.getInstance().getOauth2UserName()); 
     authDetails.setPassword(LoggerAndReader.getInstance().getOauth2password()); 
    } 
    // authDetails.setScope(Arrays.asList(new String[] {"cn mail sn givenname uid employeeNumber"})); 
    return authDetails; 
} 

実行とfuther用法:

public ResponseEntity<String> execute(String url, HttpMethod httpMethod, Object o) 
{ 
    HttpEntity request = new HttpEntity(o, this.header); 
    ResponseEntity<String> resp = null; 
    this.header.set("Authorization", token.getTokenType() + " " + token.getValue()); 
    try { 
     resp = this.client.exchange(url, httpMethod, request, String.class); 
    } catch (Exception e) { 
     String str = getStackTrace(e); 
     if (StringUtils.containsIgnoreCase(str, "SocketTimeoutException")) { 
      throw new KeycloakHTTPClientSocketException(
       "Got a SocketTimeoutException for URL:" + url + ", HTTPMethod:" + httpMethod); 
     } else 
      throw new Exception(...); 
    } 
    return resp; 
} 

さらにヘッダを追加する場合は、あなたはそれらを追加する必要があります。

public void setThisHeaderValue(String key, String value) 
{ 
    this.header.add(key, value); 
} 
関連する問題