stripped out check id endpoint interaction as it deprecated, refactored nonce checking based on spec change, pull user_id as id_token token claim

pull/105/merge
U-MITRE\mjwalsh 2012-06-13 18:29:12 -04:00 committed by nemonik
parent 901d3afff4
commit f9558f0955
7 changed files with 82 additions and 127 deletions

View File

@ -63,9 +63,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
/** /**
* The OpenID Connect Authentication Filter * Abstract OpenID Connect Authentication Filter class
*
* See README.md to to configure
* *
* @author nemonik * @author nemonik
* *
@ -74,7 +72,8 @@ public class AbstractOIDCAuthenticationFilter extends
AbstractAuthenticationProcessingFilter { AbstractAuthenticationProcessingFilter {
/** /**
* Used to remove parameters from a Request before passing it down the chain... * Used to remove parameters from a Request before passing it down the
* chain...
* *
* @author nemonik * @author nemonik
* *
@ -360,7 +359,9 @@ public class AbstractOIDCAuthenticationFilter extends
HttpServletResponse response) throws AuthenticationException, HttpServletResponse response) throws AuthenticationException,
IOException, ServletException { IOException, ServletException {
logger.debug("Request: " + request.getRequestURI() + (StringUtils.isNotBlank(request.getQueryString()) ? "?" logger.debug("Request: "
+ request.getRequestURI()
+ (StringUtils.isNotBlank(request.getQueryString()) ? "?"
+ request.getQueryString() : "")); + request.getQueryString() : ""));
return null; return null;
@ -399,6 +400,7 @@ public class AbstractOIDCAuthenticationFilter extends
// ((DefaultHttpClient) // ((DefaultHttpClient)
// httpClient).getCredentialsProvider().setCredentials(AuthScope.ANY, // httpClient).getCredentialsProvider().setCredentials(AuthScope.ANY,
// credentials); // credentials);
//
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory( HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
httpClient); httpClient);
@ -438,6 +440,8 @@ public class AbstractOIDCAuthenticationFilter extends
"Unable to obtain Access Token."); "Unable to obtain Access Token.");
} }
logger.debug("from TokenEndpoint jsonString = " + jsonString);
JsonElement jsonRoot = new JsonParser().parse(jsonString); JsonElement jsonRoot = new JsonParser().parse(jsonString);
if (jsonRoot.getAsJsonObject().get("error") != null) { if (jsonRoot.getAsJsonObject().get("error") != null) {
@ -455,8 +459,7 @@ public class AbstractOIDCAuthenticationFilter extends
} else { } else {
// Extract the id_token to insert into the // Extract the id_token
// OpenIdConnectAuthenticationToken
IdToken idToken = null; IdToken idToken = null;
@ -505,53 +508,21 @@ public class AbstractOIDCAuthenticationFilter extends
"Token Endpoint did not return a token_id"); "Token Endpoint did not return a token_id");
} }
// Handle Check ID Endpoint interaction // Clients are required to compare nonce claim in ID token to
// the nonce sent in the Authorization request. The client
// stores this value as a signed session cookie to detect a
// replay by third parties.
//
// See: OpenID Connect Messages
//
// Specifically, Section 2.1.1 entitled "ID Token"
//
// http://openid.net/specs/openid-connect-messages-1_0.html#id_token
//
// Read the paragraph describing "nonce". Required w/ implicit flow.
//
httpClient = new DefaultHttpClient(); String nonce = idToken.getClaims().getNonce();
httpClient.getParams().setParameter("http.socket.timeout",
new Integer(httpSocketTimeout));
factory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate = new RestTemplate(factory);
form = new LinkedMultiValueMap<String, String>();
form.add("access_token", jsonRoot.getAsJsonObject().get("id_token")
.getAsString());
jsonString = null;
try {
jsonString = restTemplate.postForObject(
serverConfig.getCheckIDEndpointURI(), form,
String.class);
} catch (HttpClientErrorException httpClientErrorException) {
// Handle error
logger.error("Check ID Endpoint error response: "
+ httpClientErrorException.getStatusText() + " : "
+ httpClientErrorException.getMessage());
throw new AuthenticationServiceException("Unable check token.");
}
jsonRoot = new JsonParser().parse(jsonString);
// String iss = jsonRoot.getAsJsonObject().get("iss")
// .getAsString();
String userId = jsonRoot.getAsJsonObject().get("user_id")
.getAsString();
// String aud = jsonRoot.getAsJsonObject().get("aud")
// .getAsString();
String nonce = jsonRoot.getAsJsonObject().get("nonce")
.getAsString();
// String exp = jsonRoot.getAsJsonObject().get("exp")
// .getAsString();
// Compare returned ID Token to signed session cookie
// to detect ID Token replay by third parties.
Cookie nonceSignatureCookie = WebUtils.getCookie(request, Cookie nonceSignatureCookie = WebUtils.getCookie(request,
NONCE_SIGNATURE_COOKIE_NAME); NONCE_SIGNATURE_COOKIE_NAME);
@ -572,8 +543,7 @@ public class AbstractOIDCAuthenticationFilter extends
"Possible replay attack detected! " "Possible replay attack detected! "
+ "The comparison of the nonce in the returned " + "The comparison of the nonce in the returned "
+ "ID Token to the signed session " + "ID Token to the signed session "
+ NONCE_SIGNATURE_COOKIE_NAME + NONCE_SIGNATURE_COOKIE_NAME + " failed.");
+ " failed.");
} }
} else { } else {
@ -587,15 +557,18 @@ public class AbstractOIDCAuthenticationFilter extends
} else { } else {
logger.error(NONCE_SIGNATURE_COOKIE_NAME logger.error(NONCE_SIGNATURE_COOKIE_NAME + " cookie was not found.");
+ " cookie was not found.");
throw new AuthenticationServiceException( throw new AuthenticationServiceException(
NONCE_SIGNATURE_COOKIE_NAME + " cookie was not found."); NONCE_SIGNATURE_COOKIE_NAME + " cookie was not found.");
} }
// Create an Authentication object for the token, and // pull the user_id out as a claim on the id_token
// return.
String userId = idToken.getTokenClaims().getUserId();
// construct an OpenIdConnectAuthenticationToken and return
// a Authentication object w/
OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken( OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(
userId, idToken); userId, idToken);

View File

@ -65,9 +65,6 @@ public class OIDCAuthenticationFilter extends AbstractOIDCAuthenticationFilter {
Assert.notNull(oidcServerConfig.getTokenEndpointURI(), Assert.notNull(oidcServerConfig.getTokenEndpointURI(),
"A Token ID Endpoint URI must be supplied"); "A Token ID Endpoint URI must be supplied");
Assert.notNull(oidcServerConfig.getCheckIDEndpointURI(),
"A Check ID Endpoint URI must be supplied");
Assert.notNull(oidcServerConfig.getClientId(), Assert.notNull(oidcServerConfig.getClientId(),
"A Client ID must be supplied"); "A Client ID must be supplied");
@ -113,10 +110,6 @@ public class OIDCAuthenticationFilter extends AbstractOIDCAuthenticationFilter {
oidcServerConfig.setAuthorizationEndpointURI(authorizationEndpointURI); oidcServerConfig.setAuthorizationEndpointURI(authorizationEndpointURI);
} }
public void setCheckIDEndpointURI(String checkIDEndpointURI) {
oidcServerConfig.setCheckIDEndpointURI(checkIDEndpointURI);
}
public void setClientId(String clientId) { public void setClientId(String clientId) {
oidcServerConfig.setClientId(clientId); oidcServerConfig.setClientId(clientId);
} }

View File

@ -129,8 +129,7 @@ public class OIDCAuthenticationUsingChooserFilter extends
// The Client is configured to support this Issuer // The Client is configured to support this Issuer
// Identifier // Identifier
Cookie issuerCookie = new Cookie(ISSUER_COOKIE_NAME, Cookie issuerCookie = new Cookie(ISSUER_COOKIE_NAME, issuer);
issuer);
response.addCookie(issuerCookie); response.addCookie(issuerCookie);
handleAuthorizationRequest(new SanatizedRequest(request, handleAuthorizationRequest(new SanatizedRequest(request,

View File

@ -25,8 +25,6 @@ public class OIDCServerConfiguration {
private String tokenEndpointURI; private String tokenEndpointURI;
private String checkIDEndpointURI;
private String clientSecret; private String clientSecret;
private String clientId; private String clientId;
@ -35,10 +33,6 @@ public class OIDCServerConfiguration {
return authorizationEndpointURI; return authorizationEndpointURI;
} }
public String getCheckIDEndpointURI() {
return checkIDEndpointURI;
}
public String getClientId() { public String getClientId() {
return clientId; return clientId;
} }
@ -55,10 +49,6 @@ public class OIDCServerConfiguration {
this.authorizationEndpointURI = authorizationEndpointURI; this.authorizationEndpointURI = authorizationEndpointURI;
} }
public void setCheckIDEndpointURI(String checkIDEndpointURI) {
this.checkIDEndpointURI = checkIDEndpointURI;
}
public void setClientId(String clientId) { public void setClientId(String clientId) {
this.clientId = clientId; this.clientId = clientId;
} }
@ -75,8 +65,7 @@ public class OIDCServerConfiguration {
public String toString() { public String toString() {
return "OIDCServerConfiguration [authorizationEndpointURI=" return "OIDCServerConfiguration [authorizationEndpointURI="
+ authorizationEndpointURI + ", tokenEndpointURI=" + authorizationEndpointURI + ", tokenEndpointURI="
+ tokenEndpointURI + ", checkIDEndpointURI=" + tokenEndpointURI + ", clientSecret=" + clientSecret
+ checkIDEndpointURI + ", clientSecret=" + clientSecret
+ ", clientId=" + clientId + "]"; + ", clientId=" + clientId + "]";
} }

View File

@ -24,7 +24,6 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion; import org.springframework.security.core.SpringSecurityCoreVersion;
/** /**
*
* *
* @author nemonik * @author nemonik
* *
@ -39,14 +38,16 @@ public class OpenIdConnectAuthenticationToken extends
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
/** /**
* Constructs OpenIdConnectAuthenticationToken provided
*
* @param principle * @param principle
* @param authorities * @param authorities
* @param userId * @param userId
* @param idToken * @param idToken
*/ */
public OpenIdConnectAuthenticationToken(Object principle, public OpenIdConnectAuthenticationToken(Object principle,
Collection<? extends GrantedAuthority> authorities, Collection<? extends GrantedAuthority> authorities, String userId,
String userId, IdToken idToken) { IdToken idToken) {
super(authorities); super(authorities);
@ -58,6 +59,8 @@ public class OpenIdConnectAuthenticationToken extends
} }
/** /**
* Constructs OpenIdConnectAuthenticationToken provided
*
* @param idToken * @param idToken
* @param userId * @param userId
*/ */
@ -72,7 +75,9 @@ public class OpenIdConnectAuthenticationToken extends
setAuthenticated(false); setAuthenticated(false);
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.springframework.security.core.Authentication#getCredentials() * @see org.springframework.security.core.Authentication#getCredentials()
*/ */
@Override @Override
@ -84,7 +89,9 @@ public class OpenIdConnectAuthenticationToken extends
return idToken; return idToken;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.springframework.security.core.Authentication#getPrincipal() * @see org.springframework.security.core.Authentication#getPrincipal()
*/ */
@Override @Override

View File

@ -5,12 +5,6 @@
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/> <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/> <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<dependent-module archiveName="spring-security-oauth2-1.0.0.BUILD-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/spring-security-oauth2/spring-security-oauth2">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="openid-connect-common-0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/openid-connect-common/openid-connect-common">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="java-output-path" value="/openid/target/classes"/> <property name="java-output-path" value="/openid/target/classes"/>
<property name="context-root" value="openid-connect-server"/> <property name="context-root" value="openid-connect-server"/>
</wb-module> </wb-module>