From 325a200f167f373b147ad0dbdb7673379d434475 Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Sun, 20 Jul 2014 09:27:02 -0700 Subject: [PATCH] added configurable support for different token presentation methods in user info fetcher, closes #632 --- .../connect/client/UserInfoFetcher.java | 67 ++++++++++++++----- .../connect/config/ServerConfiguration.java | 14 ++++ 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java index 35c13f5d4..5b6caf726 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java @@ -16,14 +16,21 @@ ******************************************************************************/ package org.mitre.openid.connect.client; +import java.io.IOException; +import java.net.URI; + import org.apache.http.client.HttpClient; +import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.SystemDefaultHttpClient; import org.mitre.openid.connect.config.ServerConfiguration; +import org.mitre.openid.connect.config.ServerConfiguration.UserInfoTokenMethod; import org.mitre.openid.connect.model.DefaultUserInfo; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.mitre.openid.connect.model.UserInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -42,7 +49,7 @@ public class UserInfoFetcher { private Logger logger = LoggerFactory.getLogger(UserInfoFetcher.class); - public UserInfo loadUserInfo(OIDCAuthenticationToken token) { + public UserInfo loadUserInfo(final OIDCAuthenticationToken token) { ServerConfiguration serverConfiguration = token.getServerConfiguration(); @@ -56,24 +63,54 @@ public class UserInfoFetcher { return null; } - // if we got this far, try to actually get the userinfo - HttpClient httpClient = new SystemDefaultHttpClient(); - - HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); - - RestTemplate restTemplate = new RestTemplate(factory); - - MultiValueMap form = new LinkedMultiValueMap(); - form.add("access_token", token.getAccessTokenValue()); - try { - String userInfoString = restTemplate.postForObject(serverConfiguration.getUserInfoUri(), form, String.class); + + // if we got this far, try to actually get the userinfo + HttpClient httpClient = new SystemDefaultHttpClient(); + + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); + + String userInfoString = null; + + if (serverConfiguration.getUserInfoTokenMethod() == null || serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.HEADER)) { + RestTemplate restTemplate = new RestTemplate(factory) { + + @Override + protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { + ClientHttpRequest httpRequest = super.createRequest(url, method); + httpRequest.getHeaders().add("Authorization", String.format("Bearer %s", token.getAccessTokenValue())); + return httpRequest; + } + }; + + userInfoString = restTemplate.getForObject(serverConfiguration.getUserInfoUri(), String.class); + + } else if (serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.FORM)) { + MultiValueMap form = new LinkedMultiValueMap(); + form.add("access_token", token.getAccessTokenValue()); + + RestTemplate restTemplate = new RestTemplate(factory); + userInfoString = restTemplate.postForObject(serverConfiguration.getUserInfoUri(), form, String.class); + } else if (serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.QUERY)) { + URIBuilder builder = new URIBuilder(serverConfiguration.getUserInfoUri()); + builder.setParameter("access_token", token.getAccessTokenValue()); + + RestTemplate restTemplate = new RestTemplate(factory); + userInfoString = restTemplate.getForObject(builder.toString(), String.class); + } - JsonObject userInfoJson = new JsonParser().parse(userInfoString).getAsJsonObject(); - UserInfo userInfo = DefaultUserInfo.fromJson(userInfoJson); + if (!Strings.isNullOrEmpty(userInfoString)) { - return userInfo; + JsonObject userInfoJson = new JsonParser().parse(userInfoString).getAsJsonObject(); + + UserInfo userInfo = DefaultUserInfo.fromJson(userInfoJson); + + return userInfo; + } else { + // didn't get anything, return null + return null; + } } catch (Exception e) { logger.warn("Error fetching userinfo", e); return null; diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java index 07e5e4ba5..01c7e41af 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java @@ -205,6 +205,14 @@ public class ServerConfiguration { private Boolean requireRequestUriRegistration; private String opPolicyUri; private String opTosUri; + private UserInfoTokenMethod userInfoTokenMethod; + + public enum UserInfoTokenMethod { + HEADER, + FORM, + QUERY; + } + /** * @return the authorizationEndpointUri */ @@ -657,6 +665,12 @@ public class ServerConfiguration { this.revocationEndpointUri = revocationEndpointUri; } + public UserInfoTokenMethod getUserInfoTokenMethod() { + return userInfoTokenMethod; + } + public void setUserInfoTokenMethod(UserInfoTokenMethod userInfoTokenMethod) { + this.userInfoTokenMethod = userInfoTokenMethod; + } @Override public int hashCode() { final int prime = 31;