Merge remote branch 'origin/master'
commit
ba376dfd61
|
@ -27,7 +27,7 @@ import org.apache.http.auth.AuthScope;
|
||||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
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.http.client.HttpComponentsClientHttpRequestFactory;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
@ -204,7 +204,7 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"A Client Secret must be supplied");
|
"A Client Secret must be supplied");
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyPairGenerator keyPairGenerator;
|
KeyPairGenerator keyPairGenerator;
|
||||||
try {
|
try {
|
||||||
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
@ -212,17 +212,17 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||||
publicKey = keyPair.getPublic();
|
publicKey = keyPair.getPublic();
|
||||||
privateKey = keyPair.getPrivate();
|
privateKey = keyPair.getPrivate();
|
||||||
|
|
||||||
signer = Signature.getInstance(SIGNING_ALGORITHM);
|
signer = Signature.getInstance(SIGNING_ALGORITHM);
|
||||||
} catch (GeneralSecurityException generalSecurityException) {
|
} catch (GeneralSecurityException generalSecurityException) {
|
||||||
// generalSecurityException.printStackTrace();
|
// generalSecurityException.printStackTrace();
|
||||||
throw new IllegalStateException(generalSecurityException);
|
throw new IllegalStateException(generalSecurityException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prepend the spec necessary scope
|
||||||
setScope(SCOPE + scope);
|
setScope(SCOPE + scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -244,12 +244,6 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
String errorDescription = request.getParameter("error_description");
|
String errorDescription = request.getParameter("error_description");
|
||||||
String errorURI = request.getParameter("error_uri");
|
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>();
|
Map<String, String> requestParams = new HashMap<String, String>();
|
||||||
|
|
||||||
requestParams.put("error", error);
|
requestParams.put("error", error);
|
||||||
|
@ -289,8 +283,7 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
||||||
form.add("grant_type", "authorization_code");
|
form.add("grant_type", "authorization_code");
|
||||||
form.add("code", authorizationGrant);
|
form.add("code", authorizationGrant);
|
||||||
//form.add("redirect_uri", buildRedirectURI(request));
|
form.add("redirect_uri", buildRedirectURI(request));
|
||||||
form.add("redirect_uri", Utility.findBaseUrl(request));
|
|
||||||
|
|
||||||
String jsonString = null;
|
String jsonString = null;
|
||||||
|
|
||||||
|
@ -299,6 +292,8 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
form, String.class);
|
form, String.class);
|
||||||
} catch (HttpClientErrorException httpClientErrorException) {
|
} catch (HttpClientErrorException httpClientErrorException) {
|
||||||
|
|
||||||
|
// Handle error
|
||||||
|
|
||||||
logger.error("Token Endpoint error response: "
|
logger.error("Token Endpoint error response: "
|
||||||
+ httpClientErrorException.getStatusText() + " : "
|
+ httpClientErrorException.getStatusText() + " : "
|
||||||
+ httpClientErrorException.getMessage());
|
+ httpClientErrorException.getMessage());
|
||||||
|
@ -309,6 +304,7 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
JsonElement jsonRoot = new JsonParser().parse(jsonString);
|
JsonElement jsonRoot = new JsonParser().parse(jsonString);
|
||||||
|
|
||||||
if (jsonRoot.getAsJsonObject().get("error") != null) {
|
if (jsonRoot.getAsJsonObject().get("error") != null) {
|
||||||
|
|
||||||
// Handle error
|
// Handle error
|
||||||
|
|
||||||
String error = jsonRoot.getAsJsonObject().get("error")
|
String error = jsonRoot.getAsJsonObject().get("error")
|
||||||
|
@ -320,6 +316,35 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
|
|
||||||
} else {
|
} 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
|
// Handle Check ID Endpoint interaction
|
||||||
|
|
||||||
httpClient = new DefaultHttpClient();
|
httpClient = new DefaultHttpClient();
|
||||||
|
@ -340,6 +365,8 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
checkIDEndpointURI, form, String.class);
|
checkIDEndpointURI, form, String.class);
|
||||||
} catch (HttpClientErrorException httpClientErrorException) {
|
} catch (HttpClientErrorException httpClientErrorException) {
|
||||||
|
|
||||||
|
// Handle error
|
||||||
|
|
||||||
logger.error("Check ID Endpoint error response: "
|
logger.error("Check ID Endpoint error response: "
|
||||||
+ httpClientErrorException.getStatusText()
|
+ httpClientErrorException.getStatusText()
|
||||||
+ " : " + httpClientErrorException.getMessage());
|
+ " : " + httpClientErrorException.getMessage());
|
||||||
|
@ -349,19 +376,16 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
|
|
||||||
jsonRoot = new JsonParser().parse(jsonString);
|
jsonRoot = new JsonParser().parse(jsonString);
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
// String iss = jsonRoot.getAsJsonObject().get("iss")
|
||||||
String iss = jsonRoot.getAsJsonObject().get("iss")
|
// .getAsString();
|
||||||
.getAsString();
|
String userId = jsonRoot.getAsJsonObject().get("user_id")
|
||||||
String user_id = jsonRoot.getAsJsonObject().get("user_id")
|
|
||||||
.getAsString();
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
String aud = jsonRoot.getAsJsonObject().get("aud")
|
|
||||||
.getAsString();
|
.getAsString();
|
||||||
|
// String aud = jsonRoot.getAsJsonObject().get("aud")
|
||||||
|
// .getAsString();
|
||||||
String nonce = jsonRoot.getAsJsonObject().get("nonce")
|
String nonce = jsonRoot.getAsJsonObject().get("nonce")
|
||||||
.getAsString();
|
.getAsString();
|
||||||
@SuppressWarnings("unused")
|
// String exp = jsonRoot.getAsJsonObject().get("exp")
|
||||||
String exp = jsonRoot.getAsJsonObject().get("exp")
|
// .getAsString();
|
||||||
.getAsString();
|
|
||||||
|
|
||||||
// Compare returned ID Token to signed session cookie
|
// Compare returned ID Token to signed session cookie
|
||||||
// to detect ID Token replay by third parties.
|
// to detect ID Token replay by third parties.
|
||||||
|
@ -404,7 +428,7 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
// return.
|
// return.
|
||||||
|
|
||||||
OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(
|
OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(
|
||||||
user_id);
|
idToken, userId);
|
||||||
|
|
||||||
Authentication authentication = this
|
Authentication authentication = this
|
||||||
.getAuthenticationManager().authenticate(token);
|
.getAuthenticationManager().authenticate(token);
|
||||||
|
@ -424,8 +448,7 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
urlVariables.put("response_type", "code");
|
urlVariables.put("response_type", "code");
|
||||||
urlVariables.put("client_id", clientId);
|
urlVariables.put("client_id", clientId);
|
||||||
urlVariables.put("scope", scope);
|
urlVariables.put("scope", scope);
|
||||||
//urlVariables.put("redirect_uri", buildRedirectURI(request));
|
urlVariables.put("redirect_uri", buildRedirectURI(request));
|
||||||
urlVariables.put("redirect_uri", Utility.findBaseUrl(request));
|
|
||||||
|
|
||||||
// Create a string value used to associate a user agent session
|
// Create a string value used to associate a user agent session
|
||||||
// with an ID Token to mitigate replay attacks. The value is
|
// with an ID Token to mitigate replay attacks. The value is
|
||||||
|
@ -450,62 +473,62 @@ public class OpenIdConnectAuthenticationFilter extends
|
||||||
urlVariables));
|
urlVariables));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the redirect_uri that will be sent to the Authorization Endpoint.
|
* Builds the redirect_uri that will be sent to the Authorization Endpoint.
|
||||||
* By default returns the URL of the current request.
|
* By default returns the URL of the current request.
|
||||||
*
|
*
|
||||||
* @param request the current request which is being processed by this filter
|
* @param request
|
||||||
* @return The redirect_uri.
|
* the current request which is being processed by this filter
|
||||||
*/
|
* @return The redirect_uri.
|
||||||
@SuppressWarnings("unused")
|
*/
|
||||||
private String buildRedirectURI(HttpServletRequest request) {
|
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) {
|
boolean isFirst = true;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFirst) {
|
StringBuffer sb = request.getRequestURL();
|
||||||
sb.append("?");
|
|
||||||
isFirst = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(name).append("=").append(value);
|
|
||||||
|
|
||||||
if (e.hasMoreElements()) {
|
for (Enumeration<?> e = request.getParameterNames(); e
|
||||||
sb.append("&");
|
.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) {
|
public void setAuthorizationEndpointURI(String authorizationEndpointURI) {
|
||||||
this.authorizationEndpointURI = authorizationEndpointURI;
|
this.authorizationEndpointURI = authorizationEndpointURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCheckIDEndpointURI(String checkIDEndpointURI) {
|
public void setCheckIDEndpointURI(String checkIDEndpointURI) {
|
||||||
this.checkIDEndpointURI = checkIDEndpointURI;
|
this.checkIDEndpointURI = checkIDEndpointURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientId(String clientId) {
|
public void setClientId(String clientId) {
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientSecret(String clientSecret) {
|
public void setClientSecret(String clientSecret) {
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,23 +8,45 @@ import org.springframework.security.core.AuthenticationException;
|
||||||
public class OpenIdConnectAuthenticationProvider implements
|
public class OpenIdConnectAuthenticationProvider implements
|
||||||
AuthenticationProvider, InitializingBean {
|
AuthenticationProvider, InitializingBean {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see org.springframework.security.authentication.AuthenticationProvider#
|
||||||
|
* authenticate(org.springframework.security.core.Authentication)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Authentication authenticate(Authentication arg0)
|
public Authentication authenticate(Authentication authentication)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
if (authentication instanceof OpenIdConnectAuthenticationToken) {
|
||||||
|
return authentication;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* org.springframework.security.authentication.AuthenticationProvider#supports
|
||||||
|
* (java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Class<?> arg0) {
|
public boolean supports(Class<?> authentication) {
|
||||||
// TODO Auto-generated method stub
|
return OpenIdConnectAuthenticationToken.class
|
||||||
return false;
|
.isAssignableFrom(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.mitre.client;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.mitre.openid.connect.model.IdToken;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.SpringSecurityCoreVersion;
|
import org.springframework.security.core.SpringSecurityCoreVersion;
|
||||||
|
@ -15,16 +16,22 @@ import org.springframework.security.core.SpringSecurityCoreVersion;
|
||||||
public class OpenIdConnectAuthenticationToken extends
|
public class OpenIdConnectAuthenticationToken extends
|
||||||
AbstractAuthenticationToken {
|
AbstractAuthenticationToken {
|
||||||
|
|
||||||
|
private final IdToken idToken;
|
||||||
private final String userId;
|
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
|
* @param userId
|
||||||
*/
|
*/
|
||||||
public OpenIdConnectAuthenticationToken(String userId) {
|
public OpenIdConnectAuthenticationToken(IdToken idToken, String userId) {
|
||||||
super(new ArrayList<GrantedAuthority>(0));
|
super(new ArrayList<GrantedAuthority>(0));
|
||||||
|
this.idToken = idToken;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
|
|
||||||
|
// what do I set for the principle? the idToken?
|
||||||
|
|
||||||
setAuthenticated(true);
|
setAuthenticated(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +43,10 @@ public class OpenIdConnectAuthenticationToken extends
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IdToken getIdToken() {
|
||||||
|
return idToken;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.security.core.Authentication#getPrincipal()
|
* @see org.springframework.security.core.Authentication#getPrincipal()
|
||||||
*/
|
*/
|
||||||
|
@ -49,4 +60,5 @@ public class OpenIdConnectAuthenticationToken extends
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue