slight sequence diagrams tweaks, mods to account-chooser and openid-connect-client

pull/105/merge
Michael Joseph Walsh 2012-05-16 21:12:58 -04:00
parent b06640c921
commit 6f43040587
15 changed files with 245 additions and 168 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -5,11 +5,11 @@ A Successful Client and Account Chooser Interaction
Client->End-User Browser: HTTP-Redirect\n to Account\n Chooser URL\nwith redirect_uri,\n and client_id\n parameters Client->End-User Browser: HTTP-Redirect\n to Account\n Chooser URL\nwith redirect_uri,\n and client_id\n parameters
activate End-User Browser activate End-User Browser
End-User Browser-->Account Chooser:HTTP Get/Put\n Request containing\n redirect_uri\n and client_id End-User Browser->Account Chooser:HTTP Get/Put\n Request containing\n redirect_uri\n and client_id
note right of "Account Chooser": Client Id\n is verified as\n supported, and the\n End-User selects\n an Account note right of "Account Chooser": Client Id\n is verified as\n supported, and the\n End-User selects\n an Account
deactivate End-User Browser deactivate End-User Browser
activate Account Chooser activate Account Chooser
Account Chooser-->End-User Browser:HTTP-Redirect to \nAccount Chooser URL\n with issuer parameters Account Chooser->End-User Browser:HTTP-Redirect to \nAccount Chooser URL\n with issuer parameters
activate End-User Browser activate End-User Browser
deactivate Account Chooser deactivate Account Chooser
End-User Browser->Client: HTTP Get\n Request containing the\n issuer parameter End-User Browser->Client: HTTP Get\n Request containing the\n issuer parameter
@ -21,11 +21,11 @@ The Client ID is not Supported by the Account Chooser Application
Client->End-User Browser: HTTP-Redirect to\n Account Chooser URL\n w/ redirect_uri,\n and client_id parameters Client->End-User Browser: HTTP-Redirect to\n Account Chooser URL\n w/ redirect_uri,\n and client_id parameters
activate End-User Browser activate End-User Browser
End-User Browser-->Account Chooser:HTTP Get/Put\n Request containing\n redirect_uri and client_id End-User Browser->Account Chooser:HTTP Get/Put\n Request containing\n redirect_uri and client_id
note right of "Account Chooser": Client Id is\nnot supported.\nSo, an error must\nbe returned. note right of "Account Chooser": Client Id is\nnot supported.\nSo, an error must\nbe returned.
activate Account Chooser activate Account Chooser
deactivate End-User Browser deactivate End-User Browser
Account Chooser-->End-User Browser:Returns an\nHTTP Response\ncontaining an\nerror message. Account Chooser->End-User Browser:Returns an\nHTTP Response\ncontaining an\nerror message.
deactivate Account Chooser deactivate Account Chooser
note right of "End-User Browser":The End-User is presented\nan error message\nthus ending the interaction.\n\nOptionally, the message\nMAY contain a HTML link\nto return the End-User\nback to the Client with\nan error and error description\nadded to the query component\nof the redirect_uri. note right of "End-User Browser":The End-User is presented\nan error message\nthus ending the interaction.\n\nOptionally, the message\nMAY contain a HTML link\nto return the End-User\nback to the Client with\nan error and error description\nadded to the query component\nof the redirect_uri.
activate End-User Browser activate End-User Browser
@ -38,11 +38,11 @@ End-User Cancels Account Selection
Client->End-User Browser: HTTP-Redirect to\n Account Chooser URL\nwith redirect_uri,\nand client_id parameters Client->End-User Browser: HTTP-Redirect to\n Account Chooser URL\nwith redirect_uri,\nand client_id parameters
activate End-User Browser activate End-User Browser
End-User Browser-->Account Chooser:HTTP Get/Put\n Request containing\nredirect_uri and client_id End-User Browser->Account Chooser:HTTP Get/Put\n Request containing\nredirect_uri and client_id
note right of "Account Chooser": End-User refuses\nto select an\naccount via\ncancelling. note right of "Account Chooser": End-User refuses\nto select an\naccount via\ncancelling.
deactivate End-User Browser deactivate End-User Browser
activate Account Chooser activate Account Chooser
Account Chooser-->End-User Browser:HTTP-Redirect\n to Account Chooser\n URL with error,\nand error_description\nparameters Account Chooser->End-User Browser:HTTP-Redirect\n to Account Chooser\n URL with error,\nand error_description\nparameters
activate End-User Browser activate End-User Browser
deactivate Account Chooser deactivate Account Chooser
End-User Browser->Client: HTTP Get Request\ncontaining the error,\nand error_description\nparameter End-User Browser->Client: HTTP Get Request\ncontaining the error,\nand error_description\nparameter

View File

@ -38,9 +38,9 @@
<bean name="AccountChooserConfig" class="org.mitre.account_chooser.AccountChooserConfig"> <bean name="AccountChooserConfig" class="org.mitre.account_chooser.AccountChooserConfig">
<property name="issuers"> <property name="issuers">
<map> <map>
<entry key="http://sever.example.com:8080/openid-connect-server"> <entry key="http://idsandbox.vislab.mitre.org/openid-connect-server">
<bean class="org.mitre.account_chooser.OIDCServer"> <bean class="org.mitre.account_chooser.OIDCServer">
<property name="name" value="Example Server" /> <property name="name" value="idsandbox openid-connect-server" />
</bean> </bean>
</entry> </entry>
</map> </map>

View File

@ -26,7 +26,9 @@ import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.Signature; import java.security.Signature;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -35,6 +37,7 @@ import java.util.Map;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
@ -70,6 +73,63 @@ import com.google.gson.JsonParser;
public class AbstractOIDCAuthenticationFilter extends public class AbstractOIDCAuthenticationFilter extends
AbstractAuthenticationProcessingFilter { AbstractAuthenticationProcessingFilter {
/**
* Used to remove parameters from a Request before passing it down the chain...
*
* @author nemonik
*
*/
class SanatizedRequest extends HttpServletRequestWrapper {
private List<String> paramsToBeSanatized;
public SanatizedRequest(HttpServletRequest request,
String[] paramsToBeSanatized) {
super(request);
this.paramsToBeSanatized = Arrays.asList(paramsToBeSanatized);
}
public String getParameter(String name) {
if (paramsToBeSanatized.contains(name)) {
return null;
} else {
return super.getParameter(name);
}
}
public Map<String, String[]> getParameterMap() {
Map<String, String[]> params = super.getParameterMap();
for (String paramToBeSanatized : paramsToBeSanatized) {
params.remove(paramToBeSanatized);
}
return params;
}
public Enumeration<String> getParameterNames() {
ArrayList<String> paramNames = Collections.list(super
.getParameterNames());
for (String paramToBeSanatized : paramsToBeSanatized) {
paramNames.remove(paramToBeSanatized);
}
return Collections.enumeration(paramNames);
}
public String[] getParameterValues(String name) {
if (paramsToBeSanatized.contains(name)) {
return null;
} else {
return super.getParameterValues(name);
}
}
}
protected final static int HTTP_SOCKET_TIMEOUT = 30000; protected final static int HTTP_SOCKET_TIMEOUT = 30000;
protected final static String SCOPE = "openid"; protected final static String SCOPE = "openid";
protected final static int KEY_SIZE = 1024; protected final static int KEY_SIZE = 1024;
@ -296,29 +356,34 @@ public class AbstractOIDCAuthenticationFilter extends
* javax.servlet.http.HttpServletResponse) * javax.servlet.http.HttpServletResponse)
*/ */
@Override @Override
public Authentication attemptAuthentication(HttpServletRequest arg0, public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse arg1) throws AuthenticationException, HttpServletResponse response) throws AuthenticationException,
IOException, ServletException { IOException, ServletException {
logger.debug("Request: " + request.getRequestURI() + (StringUtils.isNotBlank(request.getQueryString()) ? "?"
+ request.getQueryString() : "") );
return null; return null;
} }
/** /**
* Handles the authorization grant response * Handles the authorization grant response
* *
* @param authorizationGrant
* The Authorization grant code
* @param request * @param request
* The request from which to extract parameters and perform the * The request from which to extract parameters and perform the
* authentication * authentication
* @return The authenticated user token, or null if authentication is * @return The authenticated user token, or null if authentication is
* incomplete. * incomplete.
* @throws UnsupportedEncodingException
*/ */
protected Authentication handleAuthorizationGrantResponse( protected Authentication handleAuthorizationGrantResponse(
HttpServletRequest request, OIDCServerConfiguration serverConfig) { String authorizationGrant, HttpServletRequest request,
OIDCServerConfiguration serverConfig) {
final boolean debug = logger.isDebugEnabled(); final boolean debug = logger.isDebugEnabled();
String authorizationGrant = request.getParameter("code");
// Handle Token Endpoint interaction // Handle Token Endpoint interaction
HttpClient httpClient = new DefaultHttpClient(); HttpClient httpClient = new DefaultHttpClient();
@ -329,11 +394,11 @@ public class AbstractOIDCAuthenticationFilter extends
// TODO: basic auth is untested (it wasn't working last I // TODO: basic auth is untested (it wasn't working last I
// tested) // tested)
// UsernamePasswordCredentials credentials = new // UsernamePasswordCredentials credentials = new
// UsernamePasswordCredentials( // UsernamePasswordCredentials(serverConfig.getClientId(),
// clientId, clientSecret); // serverConfig.getClientSecret());
// ((DefaultHttpClient) httpClient).getCredentialsProvider() // ((DefaultHttpClient)
// .setCredentials(AuthScope.ANY, credentials); // httpClient).getCredentialsProvider().setCredentials(AuthScope.ANY,
// // credentials);
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory( HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
httpClient); httpClient);
@ -344,7 +409,7 @@ public class AbstractOIDCAuthenticationFilter extends
form.add("grant_type", "authorization_code"); form.add("grant_type", "authorization_code");
form.add("code", authorizationGrant); form.add("code", authorizationGrant);
form.add("redirect_uri", AbstractOIDCAuthenticationFilter form.add("redirect_uri", AbstractOIDCAuthenticationFilter
.buildRedirectURI(request, new String[] { "code" })); .buildRedirectURI(request, null));
// pass clientId and clientSecret in post of request // pass clientId and clientSecret in post of request
form.add("client_id", serverConfig.getClientId()); form.add("client_id", serverConfig.getClientId());
@ -589,8 +654,13 @@ public class AbstractOIDCAuthenticationFilter extends
// TODO: display, prompt, request, request_uri // TODO: display, prompt, request, request_uri
response.sendRedirect(AbstractOIDCAuthenticationFilter.buildURL( String authRequest = AbstractOIDCAuthenticationFilter
serverConfiguration.getAuthorizationEndpointURI(), urlVariables)); .buildURL(serverConfiguration.getAuthorizationEndpointURI(),
urlVariables);
logger.debug("Auth Request: " + authRequest);
response.sendRedirect(authRequest);
} }
/** /**

View File

@ -95,9 +95,11 @@ public class OIDCAuthenticationFilter extends AbstractOIDCAuthenticationFilter {
handleError(request, response); handleError(request, response);
} else if (request.getParameter("code") != null) { } else if (StringUtils.isNotBlank(request.getParameter("code"))) {
return handleAuthorizationGrantResponse(request, oidcServerConfig); return handleAuthorizationGrantResponse(
request.getParameter("code"), new SanatizedRequest(request,
new String[] { "code" }), oidcServerConfig);
} else { } else {

View File

@ -105,22 +105,24 @@ public class OIDCAuthenticationUsingChooserFilter extends
} else if (request.getParameter("code") != null) { } else if (request.getParameter("code") != null) {
// Which OIDC configuration? // Which OIDC configuration?
Cookie oidcAliasCookie = WebUtils.getCookie(request, Cookie issuerCookie = WebUtils.getCookie(request,
ISSUER_COOKIE_NAME); ISSUER_COOKIE_NAME);
return handleAuthorizationGrantResponse(request, return handleAuthorizationGrantResponse(
oidcServerConfigs.get(oidcAliasCookie.getValue())); request.getParameter("code"), new SanatizedRequest(request,
new String[] { "code" }),
oidcServerConfigs.get(issuerCookie.getValue()));
} else { } else {
String issuerId = request.getParameter("issuer"); String issuer = request.getParameter("issuer");
if (StringUtils.isNotBlank(issuerId)) { if (StringUtils.isNotBlank(issuer)) {
// Account Chooser UI provided and Issuer Identifier // Account Chooser UI provided and Issuer Identifier
OIDCServerConfiguration oidcServerConfig = oidcServerConfigs OIDCServerConfiguration oidcServerConfig = oidcServerConfigs
.get(issuerId); .get(issuer);
if (oidcServerConfig != null) { if (oidcServerConfig != null) {
@ -128,10 +130,11 @@ public class OIDCAuthenticationUsingChooserFilter extends
// Identifier // Identifier
Cookie issuerCookie = new Cookie(ISSUER_COOKIE_NAME, Cookie issuerCookie = new Cookie(ISSUER_COOKIE_NAME,
issuerId); issuer);
response.addCookie(issuerCookie); response.addCookie(issuerCookie);
handleAuthorizationRequest(request, response, handleAuthorizationRequest(new SanatizedRequest(request,
new String[] { "issuer" }), response,
oidcServerConfig); oidcServerConfig);
} else { } else {
@ -140,8 +143,8 @@ public class OIDCAuthenticationUsingChooserFilter extends
// Identifier // Identifier
throw new AuthenticationServiceException( throw new AuthenticationServiceException(
"Security Filter not configured for OIDC Alias: " "Security Filter not configured for issuer: "
+ issuerId); + issuer);
} }
} else { } else {
@ -155,6 +158,8 @@ public class OIDCAuthenticationUsingChooserFilter extends
OIDCAuthenticationUsingChooserFilter.buildRedirectURI( OIDCAuthenticationUsingChooserFilter.buildRedirectURI(
request, null)); request, null));
urlVariables.put("client_id", accountChooserClientID);
response.sendRedirect(OIDCAuthenticationUsingChooserFilter response.sendRedirect(OIDCAuthenticationUsingChooserFilter
.buildURL(accountChooserURI, urlVariables)); .buildURL(accountChooserURI, urlVariables));
} }