added token values into the OpenIDConnectAuthToken class and authenticator, still need to do authuserdetailsservice

pull/210/head
Justin Richer 2012-08-10 16:24:09 -04:00
parent a65504c0cb
commit 6ccbf480b3
3 changed files with 107 additions and 59 deletions

View File

@ -67,6 +67,7 @@ import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.WebUtils; import org.springframework.web.util.WebUtils;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
/** /**
@ -311,12 +312,17 @@ public class AbstractOIDCAuthenticationFilter extends
logger.debug("from TokenEndpoint jsonString = " + jsonString); logger.debug("from TokenEndpoint jsonString = " + jsonString);
JsonElement jsonRoot = new JsonParser().parse(jsonString); JsonElement jsonRoot = new JsonParser().parse(jsonString);
if (!jsonRoot.isJsonObject()) {
throw new AuthenticationServiceException("Token Endpoint did not return a JSON object: " + jsonRoot);
}
if (jsonRoot.getAsJsonObject().get("error") != null) { JsonObject tokenResponse = jsonRoot.getAsJsonObject();
if (tokenResponse.get("error") != null) {
// Handle error // Handle error
String error = jsonRoot.getAsJsonObject().get("error") String error = tokenResponse.get("error")
.getAsString(); .getAsString();
logger.error("Token Endpoint returned: " + error); logger.error("Token Endpoint returned: " + error);
@ -328,13 +334,33 @@ public class AbstractOIDCAuthenticationFilter extends
// Extract the id_token to insert into the // Extract the id_token to insert into the
// OpenIdConnectAuthenticationToken // OpenIdConnectAuthenticationToken
IdToken idToken = null; // get out all the token strings
JwtSigningAndValidationService jwtValidator = getValidatorForServer(serverConfig); String accessTokenValue = null;
String idTokenValue = null;
String refreshTokenValue = null;
if (jsonRoot.getAsJsonObject().get("id_token") != null) { if (tokenResponse.has("access_token")) {
accessTokenValue = tokenResponse.get("access_token").getAsString();
} else {
throw new AuthenticationServiceException("Token Endpoint did not return an access_token: " + jsonString);
}
if (tokenResponse.has("id_token")) {
idTokenValue = tokenResponse.get("id_token").getAsString();
} else {
logger.error("Token Endpoint did not return an id_token");
throw new AuthenticationServiceException("Token Endpoint did not return an id_token");
}
if (tokenResponse.has("refresh_token")) {
refreshTokenValue = tokenResponse.get("refresh_token").getAsString();
}
JwtSigningAndValidationService jwtValidator = getValidatorForServer(serverConfig);
IdToken idToken = null;
try { try {
idToken = IdToken.parse(jsonRoot.getAsJsonObject().get("id_token").getAsString()); idToken = IdToken.parse(idTokenValue);
} catch (AuthenticationServiceException e) { } catch (AuthenticationServiceException e) {
@ -346,31 +372,28 @@ public class AbstractOIDCAuthenticationFilter extends
throw new AuthenticationServiceException("Problem parsing id_token return from Token endpoint: " + e); throw new AuthenticationServiceException("Problem parsing id_token return from Token endpoint: " + e);
} }
if(jwtValidator.validateSignature(jsonRoot.getAsJsonObject().get("id_token").getAsString()) == false) { // validate our ID Token over a number of tests
if(!jwtValidator.validateSignature(idToken.toString())) {
throw new AuthenticationServiceException("Signature not validated"); throw new AuthenticationServiceException("Signature not validated");
} }
if(idToken.getClaims().getIssuer() == null) { if(idToken.getClaims().getIssuer() == null) {
throw new AuthenticationServiceException("Issuer is null"); throw new AuthenticationServiceException("Issuer is null");
} }
if(!idToken.getClaims().getIssuer().equals(serverConfig.getIssuer())){ if(!idToken.getClaims().getIssuer().equals(serverConfig.getIssuer())){
throw new AuthenticationServiceException("Issuers do not match"); throw new AuthenticationServiceException("Issuers do not match");
} }
if(jwtValidator.isJwtExpired(idToken)) { if(jwtValidator.isJwtExpired(idToken)) {
throw new AuthenticationServiceException("Id Token is expired"); throw new AuthenticationServiceException("Id Token is expired");
} }
if(jwtValidator.validateIssuedAt(idToken) == false) {
if(!jwtValidator.validateIssuedAt(idToken)) {
throw new AuthenticationServiceException("Id Token issuedAt failed"); throw new AuthenticationServiceException("Id Token issuedAt failed");
} }
} else {
// An error is unlikely, but it good security to check
logger.error("Token Endpoint did not return an id_token");
throw new AuthenticationServiceException("Token Endpoint did not return an id_token");
}
// Clients are required to compare nonce claim in ID token to // Clients are required to compare nonce claim in ID token to
// the nonce sent in the Authorization request. The client // the nonce sent in the Authorization request. The client
// stores this value as a signed session cookie to detect a // stores this value as a signed session cookie to detect a
@ -409,12 +432,14 @@ public class AbstractOIDCAuthenticationFilter extends
// construct an OpenIdConnectAuthenticationToken and return // construct an OpenIdConnectAuthenticationToken and return
// a Authentication object w/the userId and the idToken // a Authentication object w/the userId and the idToken
OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(userId, idToken); OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(userId, idTokenValue, accessTokenValue, refreshTokenValue);
Authentication authentication = this.getAuthenticationManager().authenticate(token); Authentication authentication = this.getAuthenticationManager().authenticate(token);
return authentication; return authentication;
} }
} }

View File

@ -68,9 +68,8 @@ public class OpenIdConnectAuthenticationProvider implements
UserDetails userDetails = userDetailsService.loadUserDetails(token); UserDetails userDetails = userDetailsService.loadUserDetails(token);
return new OpenIdConnectAuthenticationToken(userDetails, return new OpenIdConnectAuthenticationToken(userDetails,
authoritiesMapper.mapAuthorities(userDetails authoritiesMapper.mapAuthorities(userDetails.getAuthorities()), token.getUserId(),
.getAuthorities()), token.getUserId(), token.getIdTokenValue(), token.getAccessTokenValue(), token.getRefreshTokenValue());
token.getIdToken());
} }
return null; return null;

View File

@ -25,17 +25,18 @@ import org.springframework.security.core.SpringSecurityCoreVersion;
/** /**
* *
* @author nemonik * @author Michael Walsh, Justin Richer
* *
*/ */
public class OpenIdConnectAuthenticationToken extends public class OpenIdConnectAuthenticationToken extends AbstractAuthenticationToken {
AbstractAuthenticationToken {
private static final long serialVersionUID = 22100073066377804L;
private final Object principle; private final Object principle;
private final IdToken idToken; private final String idTokenValue; // string representation of the id token
private final String userId; private final String accessTokenValue; // string representation of the access token
private final String refreshTokenValue; // string representation of the refresh token
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; private final String userId; // user id (parsed from the id token)
/** /**
* Constructs OpenIdConnectAuthenticationToken provided * Constructs OpenIdConnectAuthenticationToken provided
@ -47,13 +48,15 @@ public class OpenIdConnectAuthenticationToken extends
*/ */
public OpenIdConnectAuthenticationToken(Object principle, public OpenIdConnectAuthenticationToken(Object principle,
Collection<? extends GrantedAuthority> authorities, String userId, Collection<? extends GrantedAuthority> authorities, String userId,
IdToken idToken) { String idTokenValue, String accessTokenValue, String refreshTokenValue) {
super(authorities); super(authorities);
this.principle = principle; this.principle = principle;
this.userId = userId; this.userId = userId;
this.idToken = idToken; this.idTokenValue = idTokenValue;
this.accessTokenValue = accessTokenValue;
this.refreshTokenValue = refreshTokenValue;
setAuthenticated(true); setAuthenticated(true);
} }
@ -64,13 +67,15 @@ public class OpenIdConnectAuthenticationToken extends
* @param idToken * @param idToken
* @param userId * @param userId
*/ */
public OpenIdConnectAuthenticationToken(String userId, IdToken idToken) { public OpenIdConnectAuthenticationToken(String userId, String idTokenValue, String accessTokenValue, String refreshTokenValue) {
super(new ArrayList<GrantedAuthority>(0)); super(new ArrayList<GrantedAuthority>(0));
this.principle = userId; this.principle = userId;
this.userId = userId; this.userId = userId;
this.idToken = idToken; this.idTokenValue = idTokenValue;
this.accessTokenValue = accessTokenValue;
this.refreshTokenValue = refreshTokenValue;
setAuthenticated(false); setAuthenticated(false);
} }
@ -82,11 +87,7 @@ public class OpenIdConnectAuthenticationToken extends
*/ */
@Override @Override
public Object getCredentials() { public Object getCredentials() {
return null; return accessTokenValue;
}
public IdToken getIdToken() {
return idToken;
} }
/* /*
@ -103,4 +104,27 @@ public class OpenIdConnectAuthenticationToken extends
public String getUserId() { public String getUserId() {
return userId; return userId;
} }
/**
* @return the idTokenValue
*/
public String getIdTokenValue() {
return idTokenValue;
}
/**
* @return the accessTokenValue
*/
public String getAccessTokenValue() {
return accessTokenValue;
}
/**
* @return the refreshTokenValue
*/
public String getRefreshTokenValue() {
return refreshTokenValue;
}
} }