pulled the id_token from the Token Endpoint response, and msg the OpenIdConnectAuthenticationToken constructor w/; with other code tightening in the OpenIdConnectAuthenticationToken and OpenIdConnectAuthenticationProvider.

pull/59/head
nemonik 2012-03-08 15:50:46 -05:00
parent f4129ec085
commit 539778e2c2
3 changed files with 131 additions and 74 deletions

View File

@ -27,7 +27,7 @@ import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.mitre.util.Utility;
import org.mitre.openid.connect.model.IdToken;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@ -204,7 +204,7 @@ public class OpenIdConnectAuthenticationFilter extends
throw new IllegalArgumentException(
"A Client Secret must be supplied");
}
KeyPairGenerator keyPairGenerator;
try {
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
@ -212,17 +212,17 @@ public class OpenIdConnectAuthenticationFilter extends
KeyPair keyPair = keyPairGenerator.generateKeyPair();
publicKey = keyPair.getPublic();
privateKey = keyPair.getPrivate();
signer = Signature.getInstance(SIGNING_ALGORITHM);
} catch (GeneralSecurityException generalSecurityException) {
// generalSecurityException.printStackTrace();
throw new IllegalStateException(generalSecurityException);
}
// prepend the spec necessary scope
setScope(SCOPE + scope);
}
/*
* (non-Javadoc)
*
@ -244,12 +244,6 @@ public class OpenIdConnectAuthenticationFilter extends
String errorDescription = request.getParameter("error_description");
String errorURI = request.getParameter("error_uri");
@SuppressWarnings("unused")
String state = request.getParameter("state"); // required by
// specification.
// doesn't say what
// to do w/
Map<String, String> requestParams = new HashMap<String, String>();
requestParams.put("error", error);
@ -289,8 +283,7 @@ public class OpenIdConnectAuthenticationFilter extends
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
form.add("grant_type", "authorization_code");
form.add("code", authorizationGrant);
//form.add("redirect_uri", buildRedirectURI(request));
form.add("redirect_uri", Utility.findBaseUrl(request));
form.add("redirect_uri", buildRedirectURI(request));
String jsonString = null;
@ -299,6 +292,8 @@ public class OpenIdConnectAuthenticationFilter extends
form, String.class);
} catch (HttpClientErrorException httpClientErrorException) {
// Handle error
logger.error("Token Endpoint error response: "
+ httpClientErrorException.getStatusText() + " : "
+ httpClientErrorException.getMessage());
@ -309,6 +304,7 @@ public class OpenIdConnectAuthenticationFilter extends
JsonElement jsonRoot = new JsonParser().parse(jsonString);
if (jsonRoot.getAsJsonObject().get("error") != null) {
// Handle error
String error = jsonRoot.getAsJsonObject().get("error")
@ -320,6 +316,35 @@ public class OpenIdConnectAuthenticationFilter extends
} else {
// Extract the id_token to insert into the
// OpenIdConnectAuthenticationToken
IdToken idToken = null;
if (jsonRoot.getAsJsonObject().get("id_token") != null) {
try {
idToken = IdToken.parse(jsonRoot.getAsJsonObject()
.get("id_token").getAsString());
} catch (Exception e) {
// I suspect this could happen
logger.error("Problem parsing id_token: " + e);
// e.printStackTrace();
return null;
}
} else {
// An error is unlikely, but it good security to check
logger.error("Token Endpoint did not return a token_id");
return null;
}
// Handle Check ID Endpoint interaction
httpClient = new DefaultHttpClient();
@ -340,6 +365,8 @@ public class OpenIdConnectAuthenticationFilter extends
checkIDEndpointURI, form, String.class);
} catch (HttpClientErrorException httpClientErrorException) {
// Handle error
logger.error("Check ID Endpoint error response: "
+ httpClientErrorException.getStatusText()
+ " : " + httpClientErrorException.getMessage());
@ -349,19 +376,16 @@ public class OpenIdConnectAuthenticationFilter extends
jsonRoot = new JsonParser().parse(jsonString);
@SuppressWarnings("unused")
String iss = jsonRoot.getAsJsonObject().get("iss")
.getAsString();
String user_id = jsonRoot.getAsJsonObject().get("user_id")
.getAsString();
@SuppressWarnings("unused")
String aud = jsonRoot.getAsJsonObject().get("aud")
// 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();
@SuppressWarnings("unused")
String exp = jsonRoot.getAsJsonObject().get("exp")
.getAsString();
// String exp = jsonRoot.getAsJsonObject().get("exp")
// .getAsString();
// Compare returned ID Token to signed session cookie
// to detect ID Token replay by third parties.
@ -404,7 +428,7 @@ public class OpenIdConnectAuthenticationFilter extends
// return.
OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(
user_id);
idToken, userId);
Authentication authentication = this
.getAuthenticationManager().authenticate(token);
@ -424,8 +448,7 @@ public class OpenIdConnectAuthenticationFilter extends
urlVariables.put("response_type", "code");
urlVariables.put("client_id", clientId);
urlVariables.put("scope", scope);
//urlVariables.put("redirect_uri", buildRedirectURI(request));
urlVariables.put("redirect_uri", Utility.findBaseUrl(request));
urlVariables.put("redirect_uri", buildRedirectURI(request));
// Create a string value used to associate a user agent session
// with an ID Token to mitigate replay attacks. The value is
@ -450,62 +473,62 @@ public class OpenIdConnectAuthenticationFilter extends
urlVariables));
}
}
return null;
}
/**
* Builds the redirect_uri that will be sent to the Authorization Endpoint.
* By default returns the URL of the current request.
*
* @param request the current request which is being processed by this filter
* @return The redirect_uri.
*/
@SuppressWarnings("unused")
/**
* Builds the redirect_uri that will be sent to the Authorization Endpoint.
* By default returns the URL of the current request.
*
* @param request
* the current request which is being processed by this filter
* @return The redirect_uri.
*/
private String buildRedirectURI(HttpServletRequest request) {
boolean isFirst = true;
StringBuffer sb = request.getRequestURL();
for (Enumeration<?> e = request.getParameterNames() ; e.hasMoreElements(); ) {
String name = (String) e.nextElement();
// Assume for simplicity that there is only one value
String value = request.getParameter(name);
if (value == null) {
continue;
}
boolean isFirst = true;
if (isFirst) {
sb.append("?");
isFirst = false;
}
sb.append(name).append("=").append(value);
StringBuffer sb = request.getRequestURL();
if (e.hasMoreElements()) {
sb.append("&");
}
}
for (Enumeration<?> e = request.getParameterNames(); e
.hasMoreElements();) {
return sb.toString();
}
String name = (String) e.nextElement();
// Assume for simplicity that there is only one value
String value = request.getParameter(name);
if (value == null) {
continue;
}
if (isFirst) {
sb.append("?");
isFirst = false;
}
sb.append(name).append("=").append(value);
if (e.hasMoreElements()) {
sb.append("&");
}
}
return sb.toString();
}
public void setAuthorizationEndpointURI(String authorizationEndpointURI) {
this.authorizationEndpointURI = authorizationEndpointURI;
}
public void setCheckIDEndpointURI(String checkIDEndpointURI) {
this.checkIDEndpointURI = checkIDEndpointURI;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}

View File

@ -8,23 +8,45 @@ import org.springframework.security.core.AuthenticationException;
public class OpenIdConnectAuthenticationProvider implements
AuthenticationProvider, InitializingBean {
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see org.springframework.security.authentication.AuthenticationProvider#
* authenticate(org.springframework.security.core.Authentication)
*/
@Override
public Authentication authenticate(Authentication arg0)
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
// TODO Auto-generated method stub
if (authentication instanceof OpenIdConnectAuthenticationToken) {
return authentication;
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.authentication.AuthenticationProvider#supports
* (java.lang.Class)
*/
@Override
public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return false;
public boolean supports(Class<?> authentication) {
return OpenIdConnectAuthenticationToken.class
.isAssignableFrom(authentication);
}
}

View File

@ -2,6 +2,7 @@ package org.mitre.client;
import java.util.ArrayList;
import org.mitre.openid.connect.model.IdToken;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
@ -15,16 +16,22 @@ import org.springframework.security.core.SpringSecurityCoreVersion;
public class OpenIdConnectAuthenticationToken extends
AbstractAuthenticationToken {
private final IdToken idToken;
private final String userId;
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
/**
* @param idToken
* @param userId
*/
public OpenIdConnectAuthenticationToken(String userId) {
public OpenIdConnectAuthenticationToken(IdToken idToken, String userId) {
super(new ArrayList<GrantedAuthority>(0));
this.idToken = idToken;
this.userId = userId;
// what do I set for the principle? the idToken?
setAuthenticated(true);
}
@ -36,6 +43,10 @@ public class OpenIdConnectAuthenticationToken extends
return null;
}
public IdToken getIdToken() {
return idToken;
}
/* (non-Javadoc)
* @see org.springframework.security.core.Authentication#getPrincipal()
*/
@ -49,4 +60,5 @@ public class OpenIdConnectAuthenticationToken extends
return userId;
}
}