diff --git a/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationFilter.java b/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationFilter.java index b64268491..551b1132a 100644 --- a/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationFilter.java +++ b/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationFilter.java @@ -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 requestParams = new HashMap(); requestParams.put("error", error); @@ -289,8 +283,7 @@ public class OpenIdConnectAuthenticationFilter extends MultiValueMap form = new LinkedMultiValueMap(); 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; } diff --git a/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationProvider.java b/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationProvider.java index 53c9aaf2d..dd88e4fb0 100644 --- a/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationProvider.java +++ b/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationProvider.java @@ -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); } } diff --git a/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationToken.java b/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationToken.java index 1a956ad26..9227a255d 100644 --- a/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationToken.java +++ b/server/src/main/java/org/mitre/client/OpenIdConnectAuthenticationToken.java @@ -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(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; } + }