2016-08-09 3 views
0

OAUTH2-Provider에 Broker 역할을하는 Keycloak으로 보안 된 앱의 REST API를 사용해야합니다.OAUTH2-Provider의 KeyCloak 브로커로 REST API 보안 사용

이 목적을 위해 OAuth2RestTemplate 및 ResourceOwnerPasswordDetails를 사용합니다. 제 3 자 제공 업체로부터 아무런 문제없이 액세스 토큰을 얻을 수 있지만 어떻게 사용합니까? 무기명으로 머리글에 사용하면 도움이되지 않습니다.

제안 사항? 액세스 토큰

@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. 
,369을 얻기

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

어쨌든 ... 적어도 나는이 문제를 해결하지 못했습니다. 동일한 문제가있는 경우 가장 빠르지 만 안타깝게도 securest 솔루션은 기본 인증을 사용하도록 설정하고 사용하는 것일 수 있습니다 ... 나는 그렇게했습니다 ... – 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; 
} 

실행 및 학습과 사용 :

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