gpt4 book ai didi

java - 使用 Keycloak 保护的 REST API 作为 OAUTH2-Provider 的代理

转载 作者:行者123 更新时间:2023-12-01 09:36:38 25 4
gpt4 key购买 nike

我必须使用使用 Keycloak 保护的应用程序的 REST API,该应用程序充当 OAUTH2-Provider 的代理。

为此,我使用 OAuth2RestTemplate 和 ResourceOwnerPasswordDetails。我可以毫无问题地从第三方提供商处获取访问 token ,但如何进一步使用它,这是问题。在 header 中将其用作承载者没有帮助。

有什么建议吗?

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

获取访问 token 的服务

@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.

在Keycloak中,我们还使用Authorizaion URL,但似乎不可能将其与ResourceOwnerPasswordResourceDetails一起使用。根据我的看法,也可能是这样,这是行不通的。

最佳答案

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

资源所有者密码资源详细信息:

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

要添加更多 header ,您需要添加它们:

public void setThisHeaderValue(String key, String value)
{
this.header.add(key, value);
}

关于java - 使用 Keycloak 保护的 REST API 作为 OAUTH2-Provider 的代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38845999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com