diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java index 6697a3d3ba5..3950df35564 100644 --- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java @@ -72,24 +72,6 @@ public class OpenIdCredentials implements Serializable return response; } - 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()) @@ -105,15 +87,15 @@ public class OpenIdCredentials implements Serializable String idToken = (String)response.get("id_token"); if (idToken == null) - throw new IllegalArgumentException("no id_token"); + throw new AuthenticationException("no id_token"); String accessToken = (String)response.get("access_token"); if (accessToken == null) - throw new IllegalArgumentException("no access_token"); + throw new AuthenticationException("no access_token"); String tokenType = (String)response.get("token_type"); if (!"Bearer".equalsIgnoreCase(tokenType)) - throw new IllegalArgumentException("invalid token_type"); + throw new AuthenticationException("invalid token_type"); claims = JwtDecoder.decode(idToken); if (LOG.isDebugEnabled()) @@ -128,11 +110,11 @@ public class OpenIdCredentials implements Serializable } } - private void validateClaims(OpenIdConfiguration configuration) + private void validateClaims(OpenIdConfiguration configuration) throws Exception { // 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"); + throw new AuthenticationException("Issuer Identifier MUST exactly match the iss Claim"); // The aud (audience) Claim MUST contain the client_id value. validateAudience(configuration); @@ -140,10 +122,16 @@ public class OpenIdCredentials implements Serializable // 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"); + throw new AuthenticationException("Authorized party claim value should be the client_id"); + + // Check that the ID token has not expired by checking the exp claim. + long expiry = (Long)claims.get("exp"); + long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F); + if (currentTimeSeconds > expiry) + throw new AuthenticationException("ID Token has expired"); } - private void validateAudience(OpenIdConfiguration configuration) + private void validateAudience(OpenIdConfiguration configuration) throws AuthenticationException { Object aud = claims.get("aud"); String clientId = configuration.getClientId(); @@ -152,17 +140,17 @@ public class OpenIdCredentials implements Serializable boolean isValidType = isString || isList; if (isString && !clientId.equals(aud)) - throw new IllegalArgumentException("Audience Claim MUST contain the client_id value"); + throw new AuthenticationException("Audience Claim MUST contain the client_id value"); else if (isList) { if (!Arrays.asList((Object[])aud).contains(clientId)) - throw new IllegalArgumentException("Audience Claim MUST contain the client_id value"); + throw new AuthenticationException("Audience Claim MUST contain the client_id value"); if (claims.get("azp") == null) - throw new IllegalArgumentException("A multi-audience ID token needs to contain an azp claim"); + throw new AuthenticationException("A multi-audience ID token needs to contain an azp claim"); } else if (!isValidType) - throw new IllegalArgumentException("Audience claim was not valid"); + throw new AuthenticationException("Audience claim was not valid"); } @SuppressWarnings("unchecked") @@ -185,7 +173,15 @@ public class OpenIdCredentials implements Serializable Object parsedResponse = JSON.parse(responseBody); if (!(parsedResponse instanceof Map)) - throw new IllegalStateException("Malformed response from OpenID Provider"); + throw new AuthenticationException("Malformed response from OpenID Provider"); return (Map)parsedResponse; } + + public static class AuthenticationException extends Exception + { + public AuthenticationException(String message) + { + super(message); + } + } } diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java index 974e2266dae..1327f6fffc1 100644 --- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java @@ -18,7 +18,6 @@ package org.eclipse.jetty.security.openid; -import java.security.Principal; import javax.security.auth.Subject; import javax.servlet.ServletRequest; @@ -86,8 +85,6 @@ public class OpenIdLoginService extends ContainerLifeCycle implements LoginServi try { openIdCredentials.redeemAuthCode(configuration); - if (openIdCredentials.isExpired()) - return null; } catch (Throwable e) { @@ -138,12 +135,10 @@ public class OpenIdLoginService extends ContainerLifeCycle implements LoginServi @Override public boolean validate(UserIdentity user) { - Principal userPrincipal = user.getUserPrincipal(); - if (!(userPrincipal instanceof OpenIdUserPrincipal)) + if (!(user.getUserPrincipal() instanceof OpenIdUserPrincipal)) return false; - OpenIdCredentials credentials = ((OpenIdUserPrincipal)userPrincipal).getCredentials(); - return !credentials.isExpired(); + return loginService == null || loginService.validate(user); } @Override @@ -167,5 +162,7 @@ public class OpenIdLoginService extends ContainerLifeCycle implements LoginServi @Override public void logout(UserIdentity user) { + if (loginService != null) + loginService.logout(user); } }