Skip to content

Commit

Permalink
Issue #5064 - the OpenIdCredentials should be serializable
Browse files Browse the repository at this point in the history
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
  • Loading branch information
lachlan-roberts committed Jul 20, 2020
1 parent 65de149 commit e03c740
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ public Authentication validateRequest(ServletRequest req, ServletResponse res, b
}

// Attempt to login with the provided authCode
OpenIdCredentials credentials = new OpenIdCredentials(authCode, getRedirectUri(request), _configuration);
OpenIdCredentials credentials = new OpenIdCredentials(authCode, getRedirectUri(request));
UserIdentity user = login(null, credentials, request);
if (user != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.FormContentProvider;
Expand All @@ -38,7 +37,7 @@
*
* <p>
* This is constructed with an authorization code from the authentication request. This authorization code
* is then exchanged using {@link #redeemAuthCode(HttpClient)} for a response containing the ID Token and Access Token.
* is then exchanged using {@link #redeemAuthCode(OpenIdConfiguration)} for a response containing the ID Token and Access Token.
* The response is then validated against the {@link OpenIdConfiguration}.
* </p>
*/
Expand All @@ -48,16 +47,14 @@ public class OpenIdCredentials implements Serializable
private static final long serialVersionUID = 4766053233370044796L;

private final String redirectUri;
private final OpenIdConfiguration configuration;
private String authCode;
private Map<String, Object> response;
private Map<String, Object> claims;

public OpenIdCredentials(String authCode, String redirectUri, OpenIdConfiguration configuration)
public OpenIdCredentials(String authCode, String redirectUri)
{
this.authCode = authCode;
this.redirectUri = redirectUri;
this.configuration = configuration;
}

public String getUserId()
Expand All @@ -75,7 +72,25 @@ public Map<String, Object> getResponse()
return response;
}

public void redeemAuthCode(HttpClient httpClient) throws Exception
public boolean isExpired()
{
if (authCode != null || claims == null)
return true;

// Check expiry
long expiry = (Long)claims.get("exp");
long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F);
if (currentTimeSeconds > expiry)
{
if (LOG.isDebugEnabled())
LOG.debug("OpenId Credentials expired {}", this);
return true;
}

return false;
}

public void redeemAuthCode(OpenIdConfiguration configuration) throws Exception
{
if (LOG.isDebugEnabled())
LOG.debug("redeemAuthCode() {}", this);
Expand All @@ -84,7 +99,7 @@ public void redeemAuthCode(HttpClient httpClient) throws Exception
{
try
{
response = claimAuthCode(httpClient, authCode);
response = claimAuthCode(configuration);
if (LOG.isDebugEnabled())
LOG.debug("response: {}", response);

Expand All @@ -103,7 +118,7 @@ public void redeemAuthCode(HttpClient httpClient) throws Exception
claims = JwtDecoder.decode(idToken);
if (LOG.isDebugEnabled())
LOG.debug("claims {}", claims);
validateClaims();
validateClaims(configuration);
}
finally
{
Expand All @@ -113,22 +128,22 @@ public void redeemAuthCode(HttpClient httpClient) throws Exception
}
}

private void validateClaims()
private void validateClaims(OpenIdConfiguration configuration)
{
// Issuer Identifier for the OpenID Provider MUST exactly match the value of the iss (issuer) Claim.
if (!configuration.getIssuer().equals(claims.get("iss")))
throw new IllegalArgumentException("Issuer Identifier MUST exactly match the iss Claim");

// The aud (audience) Claim MUST contain the client_id value.
validateAudience();
validateAudience(configuration);

// If an azp (authorized party) Claim is present, verify that its client_id is the Claim Value.
Object azp = claims.get("azp");
if (azp != null && !configuration.getClientId().equals(azp))
throw new IllegalArgumentException("Authorized party claim value should be the client_id");
}

private void validateAudience()
private void validateAudience(OpenIdConfiguration configuration)
{
Object aud = claims.get("aud");
String clientId = configuration.getClientId();
Expand All @@ -150,25 +165,8 @@ else if (!isValidType)
throw new IllegalArgumentException("Audience claim was not valid");
}

public boolean isExpired()
{
if (authCode != null || claims == null)
return true;

// Check expiry
long expiry = (Long)claims.get("exp");
long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F);
if (currentTimeSeconds > expiry)
{
if (LOG.isDebugEnabled())
LOG.debug("OpenId Credentials expired {}", this);
return true;
}

return false;
}

private Map<String, Object> claimAuthCode(HttpClient httpClient, String authCode) throws Exception
@SuppressWarnings("unchecked")
private Map<String, Object> claimAuthCode(OpenIdConfiguration configuration) throws Exception
{
Fields fields = new Fields();
fields.add("code", authCode);
Expand All @@ -177,7 +175,7 @@ private Map<String, Object> claimAuthCode(HttpClient httpClient, String authCode
fields.add("redirect_uri", redirectUri);
fields.add("grant_type", "authorization_code");
FormContentProvider formContentProvider = new FormContentProvider(fields);
Request request = httpClient.POST(configuration.getTokenEndpoint())
Request request = configuration.getHttpClient().POST(configuration.getTokenEndpoint())
.content(formContentProvider)
.timeout(10, TimeUnit.SECONDS);
ContentResponse response = request.send();
Expand All @@ -188,6 +186,6 @@ private Map<String, Object> claimAuthCode(HttpClient httpClient, String authCode
Object parsedResponse = JSON.parse(responseBody);
if (!(parsedResponse instanceof Map))
throw new IllegalStateException("Malformed response from OpenID Provider");
return (Map)parsedResponse;
return (Map<String, Object>)parsedResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import javax.security.auth.Subject;
import javax.servlet.ServletRequest;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.server.UserIdentity;
Expand All @@ -43,7 +42,6 @@ public class OpenIdLoginService extends ContainerLifeCycle implements LoginServi

private final OpenIdConfiguration configuration;
private final LoginService loginService;
private final HttpClient httpClient;
private IdentityService identityService;
private boolean authenticateNewUsers;

Expand All @@ -63,7 +61,6 @@ public OpenIdLoginService(OpenIdConfiguration configuration, LoginService loginS
{
this.configuration = configuration;
this.loginService = loginService;
this.httpClient = configuration.getHttpClient();
addBean(this.configuration);
addBean(this.loginService);
}
Expand All @@ -88,7 +85,7 @@ public UserIdentity login(String identifier, Object credentials, ServletRequest
OpenIdCredentials openIdCredentials = (OpenIdCredentials)credentials;
try
{
openIdCredentials.redeemAuthCode(httpClient);
openIdCredentials.redeemAuthCode(configuration);
if (openIdCredentials.isExpired())
return null;
}
Expand Down

0 comments on commit e03c740

Please sign in to comment.