diff --git a/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java b/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java index 0494290e5..85cccd261 100644 --- a/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java +++ b/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java @@ -27,178 +27,178 @@ import com.google.gson.JsonParser; public class IntrospectingTokenService implements ResourceServerTokenServices { - - private String clientId; - private String clientSecret; - private String introspectionUrl; - - // Inner class to store in the hash map - private class TokenCacheObject { OAuth2AccessToken token; OAuth2Authentication auth; - private TokenCacheObject(OAuth2AccessToken token, OAuth2Authentication auth) { - this.token = token; - this.auth = auth; - } - } - private Map authCache = new HashMap(); - public String getIntrospectionUrl() { - return introspectionUrl; - } + private String clientId; + private String clientSecret; + private String introspectionUrl; - public void setIntrospectionUrl(String introspectionUrl) { - this.introspectionUrl = introspectionUrl; - } + // Inner class to store in the hash map + private class TokenCacheObject { OAuth2AccessToken token; OAuth2Authentication auth; + private TokenCacheObject(OAuth2AccessToken token, OAuth2Authentication auth) { + this.token = token; + this.auth = auth; + } + } + private Map authCache = new HashMap(); - public String getClientId() { - return clientId; - } + public String getIntrospectionUrl() { + return introspectionUrl; + } - public void setClientId(String clientId) { - this.clientId = clientId; - } + public void setIntrospectionUrl(String introspectionUrl) { + this.introspectionUrl = introspectionUrl; + } - public String getClientSecret() { - return clientSecret; - } + public String getClientId() { + return clientId; + } - public void setClientSecret(String clientSecret) { - this.clientSecret = clientSecret; - } - - // Check if there is a token and authentication in the cache - // and check if it is not expired. - private TokenCacheObject checkCache(String key) { - if(authCache.containsKey(key)) { - TokenCacheObject tco = authCache.get(key); - if (tco.token.getExpiration().after(new Date())) { - return tco; - } else { - // if the token is expired, don't keep things around. - authCache.remove(key); - } - } - return null; - } - - private OAuth2Request createStoredRequest(final JsonObject token) { - clientId = token.get("client_id").getAsString(); - Set scopes = new HashSet(); - for (JsonElement e : token.get("scope").getAsJsonArray()) { - scopes.add(e.getAsString()); - } - Map parameters = new HashMap(); - parameters.put("client_id", clientId); - parameters.put("scope", OAuth2Utils.formatParameterList(scopes)); - OAuth2Request storedRequest = new OAuth2Request(parameters, clientId, null, true, scopes, null, null, null); - return storedRequest; - - } - - // create a default authentication object with authority ROLE_API - private Authentication createAuthentication(JsonObject token){ - // TODO: make role/authority configurable somehow - return new PreAuthenticatedAuthenticationToken(token.get("subject").getAsString(), null, AuthorityUtils.createAuthorityList("ROLE_API")); - } - - private OAuth2AccessToken createAccessToken(final JsonObject token, final String tokenString){ - OAuth2AccessToken accessToken = new OAuth2AccessTokenImpl(token, tokenString); - return accessToken; - } - - // Validate a token string against the introspection endpoint, - // then parse it and store it in the local cache. Return true on - // sucess, false otherwise. - private boolean parseToken(String accessToken) { - String validatedToken = null; - // Use the SpringFramework RestTemplate to send the request to the endpoint - - RestTemplate restTemplate = new RestTemplate(); - MultiValueMap form = new LinkedMultiValueMap(); - form.add("token",accessToken); - form.add("client_id", this.clientId); - form.add("client_secret", this.clientSecret); - - try { - validatedToken = restTemplate.postForObject(introspectionUrl, form, String.class); - } catch (RestClientException rce) { - // TODO: LOG THIS!? - LoggerFactory.getLogger(IntrospectingTokenService.class).error("validateToken", rce); - } - if (validatedToken != null) { - // parse the json - JsonElement jsonRoot = new JsonParser().parse(validatedToken); - if (!jsonRoot.isJsonObject()) { - return false; // didn't get a proper JSON object - } - - JsonObject tokenResponse = jsonRoot.getAsJsonObject(); - - if (tokenResponse.get("error") != null) { - // report an error? - return false; - } - - if (!tokenResponse.get("valid").getAsBoolean()){ - // non-valid token - return false; - } - // create an OAuth2Authentication - OAuth2Authentication auth = new OAuth2Authentication(createStoredRequest(tokenResponse), createAuthentication(tokenResponse)); - // create an OAuth2AccessToken - OAuth2AccessToken token = createAccessToken(tokenResponse, accessToken); - - if (token.getExpiration().after(new Date())){ - // Store them in the cache - authCache.put(accessToken, new TokenCacheObject(token,auth)); - - return true; - } - } - - // If we never put a token and an authentication in the cache... - return false; - } - - @Override - public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException { - // First check if the in memory cache has an Authentication object, and that it is still valid - // If Valid, return it - TokenCacheObject cacheAuth = checkCache(accessToken); - if (cacheAuth != null) { - return cacheAuth.auth; - } else { - if (parseToken(accessToken)) { - cacheAuth = authCache.get(accessToken); - if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) { - return cacheAuth.auth; - } else { - return null; - } - } else { - return null; - } - } - } + public void setClientId(String clientId) { + this.clientId = clientId; + } - @Override - public OAuth2AccessToken readAccessToken(String accessToken) { - // First check if the in memory cache has a Token object, and that it is still valid - // If Valid, return it - TokenCacheObject cacheAuth = checkCache(accessToken); - if (cacheAuth != null) { - return cacheAuth.token; - } else { - if (parseToken(accessToken)) { - cacheAuth = authCache.get(accessToken); - if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) { - return cacheAuth.token; - } else { - return null; - } - } else { - return null; - } - } - } + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + // Check if there is a token and authentication in the cache + // and check if it is not expired. + private TokenCacheObject checkCache(String key) { + if(authCache.containsKey(key)) { + TokenCacheObject tco = authCache.get(key); + if (tco.token.getExpiration().after(new Date())) { + return tco; + } else { + // if the token is expired, don't keep things around. + authCache.remove(key); + } + } + return null; + } + + private OAuth2Request createStoredRequest(final JsonObject token) { + clientId = token.get("client_id").getAsString(); + Set scopes = new HashSet(); + for (JsonElement e : token.get("scope").getAsJsonArray()) { + scopes.add(e.getAsString()); + } + Map parameters = new HashMap(); + parameters.put("client_id", clientId); + parameters.put("scope", OAuth2Utils.formatParameterList(scopes)); + OAuth2Request storedRequest = new OAuth2Request(parameters, clientId, null, true, scopes, null, null, null); + return storedRequest; + + } + + // create a default authentication object with authority ROLE_API + private Authentication createAuthentication(JsonObject token){ + // TODO: make role/authority configurable somehow + return new PreAuthenticatedAuthenticationToken(token.get("subject").getAsString(), null, AuthorityUtils.createAuthorityList("ROLE_API")); + } + + private OAuth2AccessToken createAccessToken(final JsonObject token, final String tokenString){ + OAuth2AccessToken accessToken = new OAuth2AccessTokenImpl(token, tokenString); + return accessToken; + } + + // Validate a token string against the introspection endpoint, + // then parse it and store it in the local cache. Return true on + // sucess, false otherwise. + private boolean parseToken(String accessToken) { + String validatedToken = null; + // Use the SpringFramework RestTemplate to send the request to the endpoint + + RestTemplate restTemplate = new RestTemplate(); + MultiValueMap form = new LinkedMultiValueMap(); + form.add("token",accessToken); + form.add("client_id", this.clientId); + form.add("client_secret", this.clientSecret); + + try { + validatedToken = restTemplate.postForObject(introspectionUrl, form, String.class); + } catch (RestClientException rce) { + // TODO: LOG THIS!? + LoggerFactory.getLogger(IntrospectingTokenService.class).error("validateToken", rce); + } + if (validatedToken != null) { + // parse the json + JsonElement jsonRoot = new JsonParser().parse(validatedToken); + if (!jsonRoot.isJsonObject()) { + return false; // didn't get a proper JSON object + } + + JsonObject tokenResponse = jsonRoot.getAsJsonObject(); + + if (tokenResponse.get("error") != null) { + // report an error? + return false; + } + + if (!tokenResponse.get("valid").getAsBoolean()){ + // non-valid token + return false; + } + // create an OAuth2Authentication + OAuth2Authentication auth = new OAuth2Authentication(createStoredRequest(tokenResponse), createAuthentication(tokenResponse)); + // create an OAuth2AccessToken + OAuth2AccessToken token = createAccessToken(tokenResponse, accessToken); + + if (token.getExpiration().after(new Date())){ + // Store them in the cache + authCache.put(accessToken, new TokenCacheObject(token,auth)); + + return true; + } + } + + // If we never put a token and an authentication in the cache... + return false; + } + + @Override + public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException { + // First check if the in memory cache has an Authentication object, and that it is still valid + // If Valid, return it + TokenCacheObject cacheAuth = checkCache(accessToken); + if (cacheAuth != null) { + return cacheAuth.auth; + } else { + if (parseToken(accessToken)) { + cacheAuth = authCache.get(accessToken); + if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) { + return cacheAuth.auth; + } else { + return null; + } + } else { + return null; + } + } + } + + @Override + public OAuth2AccessToken readAccessToken(String accessToken) { + // First check if the in memory cache has a Token object, and that it is still valid + // If Valid, return it + TokenCacheObject cacheAuth = checkCache(accessToken); + if (cacheAuth != null) { + return cacheAuth.token; + } else { + if (parseToken(accessToken)) { + cacheAuth = authCache.get(accessToken); + if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) { + return cacheAuth.token; + } else { + return null; + } + } else { + return null; + } + } + } } diff --git a/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/OAuth2AccessTokenImpl.java b/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/OAuth2AccessTokenImpl.java index 5ec2cb774..692d7beb9 100644 --- a/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/OAuth2AccessTokenImpl.java +++ b/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/OAuth2AccessTokenImpl.java @@ -20,73 +20,73 @@ import com.google.gson.JsonObject; public class OAuth2AccessTokenImpl implements OAuth2AccessToken { - private JsonObject token; - private String tokenString; - private Set scopes = null; - private Date expireDate; - - - public OAuth2AccessTokenImpl(JsonObject token, String tokenString) { - this.token = token; - this.tokenString = tokenString; - scopes = new HashSet(); - for (JsonElement e : token.get("scope").getAsJsonArray()) { - scopes.add(e.getAsString()); - } - - DateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - try { - expireDate = dateFormater.parse(token.get("expires_at").getAsString()); - } catch (ParseException ex) { - Logger.getLogger(IntrospectingTokenService.class.getName()).log(Level.SEVERE, null, ex); - } - } + private JsonObject token; + private String tokenString; + private Set scopes = null; + private Date expireDate; - @Override - public Map getAdditionalInformation() { - return null; - } + public OAuth2AccessTokenImpl(JsonObject token, String tokenString) { + this.token = token; + this.tokenString = tokenString; + scopes = new HashSet(); + for (JsonElement e : token.get("scope").getAsJsonArray()) { + scopes.add(e.getAsString()); + } - @Override - public Set getScope() { - return scopes; - } + DateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + try { + expireDate = dateFormater.parse(token.get("expires_at").getAsString()); + } catch (ParseException ex) { + Logger.getLogger(IntrospectingTokenService.class.getName()).log(Level.SEVERE, null, ex); + } + } - @Override - public OAuth2RefreshToken getRefreshToken() { - return null; - } - @Override - public String getTokenType() { - return BEARER_TYPE; - } + @Override + public Map getAdditionalInformation() { + return null; + } - @Override - public boolean isExpired() { - if (expireDate != null && expireDate.before(new Date())) { - return true; - } - return false; - } + @Override + public Set getScope() { + return scopes; + } - @Override - public Date getExpiration() { - return expireDate; - } + @Override + public OAuth2RefreshToken getRefreshToken() { + return null; + } - @Override - public int getExpiresIn() { - if (expireDate != null) { - return (int)TimeUnit.MILLISECONDS.toSeconds(expireDate.getTime() - (new Date()).getTime()); - } - return 0; - } + @Override + public String getTokenType() { + return BEARER_TYPE; + } - @Override - public String getValue() { - return tokenString; - } + @Override + public boolean isExpired() { + if (expireDate != null && expireDate.before(new Date())) { + return true; + } + return false; + } + + @Override + public Date getExpiration() { + return expireDate; + } + + @Override + public int getExpiresIn() { + if (expireDate != null) { + return (int)TimeUnit.MILLISECONDS.toSeconds(expireDate.getTime() - (new Date()).getTime()); + } + return 0; + } + + @Override + public String getValue() { + return tokenString; + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java index 87afddd3b..6b8fa9eb9 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java @@ -20,8 +20,6 @@ import java.math.BigInteger; import java.security.SecureRandom; import java.text.ParseException; import java.util.Date; -import java.util.HashMap; -import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -29,8 +27,6 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.impl.client.DefaultHttpClient; import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.impl.JWKSetSigningAndValidationServiceCacheService; @@ -74,7 +70,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected final static int HTTP_SOCKET_TIMEOUT = 30000; protected final static String FILTER_PROCESSES_URL = "/openid_connect_login"; - + // Allow for time sync issues by having a window of X seconds. private int timeSkewAllowance = 300; @@ -86,7 +82,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi private ClientConfigurationService clients; private IssuerService issuerService; private AuthRequestUrlBuilder authRequestBuilder; - + protected int httpSocketTimeout = HTTP_SOCKET_TIMEOUT; /** @@ -119,18 +115,18 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi // there's an error coming back from the server, need to handle this handleError(request, response); return null; // no auth, response is sent to display page or something - + } else if (!Strings.isNullOrEmpty(request.getParameter("code"))) { // we got back the code, need to process this to get our tokens Authentication auth = handleAuthorizationCodeResponse(request, response); return auth; - + } else { - + // not an error, not a code, must be an initial login of some type handleAuthorizationRequest(request, response); - + return null; // no auth, response redirected to the server's Auth Endpoint (or possibly to the account chooser) } @@ -149,33 +145,33 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(); - + IssuerServiceResponse issResp = issuerService.getIssuer(request); - + if (issResp.shouldRedirect()) { response.sendRedirect(issResp.getRedirectUrl()); } else { String issuer = issResp.getIssuer(); - + session.setAttribute(ISSUER_SESSION_VARIABLE, issuer); - + ServerConfiguration serverConfig = servers.getServerConfiguration(issuer); ClientDetails clientConfig = clients.getClientConfiguration(issuer); - + // our redirect URI is this current URL, with no query parameters String redirectUri = request.getRequestURL().toString(); session.setAttribute(REDIRECT_URI_SESION_VARIABLE, redirectUri); - + // this value comes back in the id token and is checked there String nonce = createNonce(session); - + // this value comes back in the auth code response String state = createState(session); - + String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state); - + logger.debug("Auth Request: " + authRequest); - + response.sendRedirect(authRequest); } } @@ -190,9 +186,9 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected Authentication handleAuthorizationCodeResponse(HttpServletRequest request, HttpServletResponse response) { String authorizationCode = request.getParameter("code"); - + HttpSession session = request.getSession(); - + // check for state, if it doesn't match we bail early String storedState = getStoredState(session); if (!StringUtils.isBlank(storedState)) { @@ -204,20 +200,20 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi // look up the issuer that we set out to talk to String issuer = getStoredSessionString(session, ISSUER_SESSION_VARIABLE); - + // pull the configurations based on that issuer ServerConfiguration serverConfig = servers.getServerConfiguration(issuer); ClientDetails clientConfig = clients.getClientConfiguration(issuer); - + MultiValueMap form = new LinkedMultiValueMap(); form.add("grant_type", "authorization_code"); form.add("code", authorizationCode); - + String redirectUri = getStoredSessionString(session, REDIRECT_URI_SESION_VARIABLE); if (redirectUri != null) { form.add("redirect_uri", redirectUri); } - + // Handle Token Endpoint interaction DefaultHttpClient httpClient = new DefaultHttpClient(); @@ -232,7 +228,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi */ form.add("client_id", clientConfig.getClientId()); form.add("client_secret", clientConfig.getClientSecret()); - /**/ + /**/ HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); @@ -257,14 +253,14 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi } logger.debug("from TokenEndpoint jsonString = " + jsonString); - + JsonElement jsonRoot = new JsonParser().parse(jsonString); if (!jsonRoot.isJsonObject()) { throw new AuthenticationServiceException("Token Endpoint did not return a JSON object: " + jsonRoot); } JsonObject tokenResponse = jsonRoot.getAsJsonObject(); - + if (tokenResponse.get("error") != null) { // Handle error @@ -279,125 +275,125 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi // Extract the id_token to insert into the // OIDCAuthenticationToken - + // get out all the token strings String accessTokenValue = null; String idTokenValue = null; String refreshTokenValue = null; - + if (tokenResponse.has("access_token")) { accessTokenValue = tokenResponse.get("access_token").getAsString(); } else { throw new AuthenticationServiceException("Token Endpoint did not return an access_token: " + jsonString); } - + if (tokenResponse.has("id_token")) { idTokenValue = tokenResponse.get("id_token").getAsString(); } else { logger.error("Token Endpoint did not return an id_token"); throw new AuthenticationServiceException("Token Endpoint did not return an id_token"); } - + if (tokenResponse.has("refresh_token")) { refreshTokenValue = tokenResponse.get("refresh_token").getAsString(); } - + try { - SignedJWT idToken = SignedJWT.parse(idTokenValue); + SignedJWT idToken = SignedJWT.parse(idTokenValue); - // validate our ID Token over a number of tests - ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet(); - - // check the signature - JwtSigningAndValidationService jwtValidator = validationServices.get(serverConfig.getJwksUri()); - if (jwtValidator != null) { - if(!jwtValidator.validateSignature(idToken)) { - throw new AuthenticationServiceException("Signature validation failed"); - } - } else { - logger.info("No validation service found. Skipping signature validation"); - } - - // check the issuer - if (idClaims.getIssuer() == null) { - throw new AuthenticationServiceException("Id Token Issuer is null"); - } else if (!idClaims.getIssuer().equals(serverConfig.getIssuer())){ - throw new AuthenticationServiceException("Issuers do not match, expected " + serverConfig.getIssuer() + " got " + idClaims.getIssuer()); - } - - // check expiration - if (idClaims.getExpirationTime() == null) { - throw new AuthenticationServiceException("Id Token does not have required expiration claim"); - } else { - // it's not null, see if it's expired - Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000)); - if (now.after(idClaims.getExpirationTime())) { - throw new AuthenticationServiceException("Id Token is expired: " + idClaims.getExpirationTime()); - } - } - - // check not before - if (idClaims.getNotBeforeTime() != null) { - Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); - if (now.before(idClaims.getNotBeforeTime())){ - throw new AuthenticationServiceException("Id Token not valid untill: " + idClaims.getNotBeforeTime()); - } - } - - // check issued at - if (idClaims.getIssueTime() == null) { - throw new AuthenticationServiceException("Id Token does not have required issued-at claim"); - } else { - // since it's not null, see if it was issued in the future - Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); - if (now.before(idClaims.getIssueTime())) { - throw new AuthenticationServiceException("Id Token was issued in the future: " + idClaims.getIssueTime()); - } - } - - // check audience - if (idClaims.getAudience() == null) { - throw new AuthenticationServiceException("Id token audience is null"); - } else if (!idClaims.getAudience().contains(clientConfig.getClientId())) { - throw new AuthenticationServiceException("Audience does not match, expected " + clientConfig.getClientId() + " got " + idClaims.getAudience()); - } - - // compare the nonce to our stored claim - // FIXME: Nimbus claims as strings? - String nonce = (String) idClaims.getCustomClaim("nonce"); - if (StringUtils.isBlank(nonce)) { - - logger.error("ID token did not contain a nonce claim."); + // validate our ID Token over a number of tests + ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet(); - throw new AuthenticationServiceException("ID token did not contain a nonce claim."); - } + // check the signature + JwtSigningAndValidationService jwtValidator = validationServices.get(serverConfig.getJwksUri()); + if (jwtValidator != null) { + if(!jwtValidator.validateSignature(idToken)) { + throw new AuthenticationServiceException("Signature validation failed"); + } + } else { + logger.info("No validation service found. Skipping signature validation"); + } - String storedNonce = getStoredNonce(session); - if (!nonce.equals(storedNonce)) { - logger.error("Possible replay attack detected! The comparison of the nonce in the returned " - + "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + "."); + // check the issuer + if (idClaims.getIssuer() == null) { + throw new AuthenticationServiceException("Id Token Issuer is null"); + } else if (!idClaims.getIssuer().equals(serverConfig.getIssuer())){ + throw new AuthenticationServiceException("Issuers do not match, expected " + serverConfig.getIssuer() + " got " + idClaims.getIssuer()); + } - throw new AuthenticationServiceException( - "Possible replay attack detected! The comparison of the nonce in the returned " - + "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + "."); - } + // check expiration + if (idClaims.getExpirationTime() == null) { + throw new AuthenticationServiceException("Id Token does not have required expiration claim"); + } else { + // it's not null, see if it's expired + Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000)); + if (now.after(idClaims.getExpirationTime())) { + throw new AuthenticationServiceException("Id Token is expired: " + idClaims.getExpirationTime()); + } + } - // pull the subject (user id) out as a claim on the id_token - - String userId = idClaims.getSubject(); - - // construct an OIDCAuthenticationToken and return a Authentication object w/the userId and the idToken - - OIDCAuthenticationToken token = new OIDCAuthenticationToken(userId, idClaims.getIssuer(), serverConfig, idTokenValue, accessTokenValue, refreshTokenValue); + // check not before + if (idClaims.getNotBeforeTime() != null) { + Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); + if (now.before(idClaims.getNotBeforeTime())){ + throw new AuthenticationServiceException("Id Token not valid untill: " + idClaims.getNotBeforeTime()); + } + } - Authentication authentication = this.getAuthenticationManager().authenticate(token); + // check issued at + if (idClaims.getIssueTime() == null) { + throw new AuthenticationServiceException("Id Token does not have required issued-at claim"); + } else { + // since it's not null, see if it was issued in the future + Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); + if (now.before(idClaims.getIssueTime())) { + throw new AuthenticationServiceException("Id Token was issued in the future: " + idClaims.getIssueTime()); + } + } + + // check audience + if (idClaims.getAudience() == null) { + throw new AuthenticationServiceException("Id token audience is null"); + } else if (!idClaims.getAudience().contains(clientConfig.getClientId())) { + throw new AuthenticationServiceException("Audience does not match, expected " + clientConfig.getClientId() + " got " + idClaims.getAudience()); + } + + // compare the nonce to our stored claim + // FIXME: Nimbus claims as strings? + String nonce = (String) idClaims.getCustomClaim("nonce"); + if (StringUtils.isBlank(nonce)) { + + logger.error("ID token did not contain a nonce claim."); + + throw new AuthenticationServiceException("ID token did not contain a nonce claim."); + } + + String storedNonce = getStoredNonce(session); + if (!nonce.equals(storedNonce)) { + logger.error("Possible replay attack detected! The comparison of the nonce in the returned " + + "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + "."); + + throw new AuthenticationServiceException( + "Possible replay attack detected! The comparison of the nonce in the returned " + + "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + "."); + } + + // pull the subject (user id) out as a claim on the id_token + + String userId = idClaims.getSubject(); + + // construct an OIDCAuthenticationToken and return a Authentication object w/the userId and the idToken + + OIDCAuthenticationToken token = new OIDCAuthenticationToken(userId, idClaims.getIssuer(), serverConfig, idTokenValue, accessTokenValue, refreshTokenValue); + + Authentication authentication = this.getAuthenticationManager().authenticate(token); + + return authentication; + } catch (ParseException e) { + throw new AuthenticationServiceException("Couldn't parse idToken: ", e); + } - return authentication; - } catch (ParseException e) { - throw new AuthenticationServiceException("Couldn't parse idToken: ", e); - } - } } @@ -436,7 +432,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi return null; } } - + /** * Create a cryptographically random nonce and store it in the session * @param session @@ -457,7 +453,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected static String getStoredNonce(HttpSession session) { return getStoredSessionString(session, NONCE_SESSION_VARIABLE); } - + /** * Create a cryptographically random state and store it in the session * @param session @@ -466,10 +462,10 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected static String createState(HttpSession session) { String state = new BigInteger(50, new SecureRandom()).toString(16); session.setAttribute(STATE_SESSION_VARIABLE, state); - + return state; } - + /** * Get the state we stored in the session * @param session @@ -478,14 +474,14 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected static String getStoredState(HttpSession session) { return getStoredSessionString(session, STATE_SESSION_VARIABLE); } - - - + + + // // Getters and setters for configuration variables // - - + + public int getTimeSkewAllowance() { return timeSkewAllowance; } @@ -562,6 +558,6 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi */ public void setAuthRequestUrlBuilder(AuthRequestUrlBuilder authRequestBuilder) { this.authRequestBuilder = authRequestBuilder; - } - + } + } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationProvider.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationProvider.java index ae50be245..14a907b6a 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationProvider.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationProvider.java @@ -35,10 +35,10 @@ import com.google.common.collect.Sets; * */ public class OIDCAuthenticationProvider implements - AuthenticationProvider, InitializingBean { +AuthenticationProvider, InitializingBean { private UserInfoFetcher userInfoFetcher = new UserInfoFetcher(); - + private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); /* @@ -70,22 +70,22 @@ public class OIDCAuthenticationProvider implements // Default authorities set // TODO: let this be configured Collection authorities = Sets.newHashSet(new SimpleGrantedAuthority("ROLE_USER")); - + OIDCAuthenticationToken token = (OIDCAuthenticationToken) authentication; UserInfo userInfo = userInfoFetcher.loadUserInfo(token); if (userInfo == null) { // TODO: user Info not found -- error? - } else { + } else { if (!Strings.isNullOrEmpty(userInfo.getSub()) && !userInfo.getSub().equals(token.getUserId())) { // the userinfo came back and the user_id fields don't match what was in the id_token throw new UsernameNotFoundException("user_id mismatch between id_token and user_info call: " + userInfo.getSub() + " / " + token.getUserId()); } } - - return new OIDCAuthenticationToken(token.getUserId(), - token.getIssuer(), + + return new OIDCAuthenticationToken(token.getUserId(), + token.getIssuer(), userInfo, authoritiesMapper.mapAuthorities(authorities), token.getIdTokenValue(), token.getAccessTokenValue(), token.getRefreshTokenValue()); } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationToken.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationToken.java index 8cf1611cc..fb6527852 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationToken.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationToken.java @@ -32,8 +32,8 @@ import com.google.common.collect.ImmutableMap; */ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { - private static final long serialVersionUID = 22100073066377804L; - + private static final long serialVersionUID = 22100073066377804L; + private final Object principal; private final String idTokenValue; // string representation of the id token private final String accessTokenValue; // string representation of the access token @@ -43,7 +43,7 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { private final transient ServerConfiguration serverConfiguration; // server configuration used to fulfill this token, don't serialize it private final transient UserInfo userInfo; // user info container, don't serialize it b/c it might be huge and can be re-fetched - + /** * Constructs OIDCAuthenticationToken with a full set of authorities, marking this as authenticated. * @@ -55,7 +55,7 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { * @param principal * @param idToken */ - public OIDCAuthenticationToken(String userId, String issuer, + public OIDCAuthenticationToken(String userId, String issuer, UserInfo userInfo, Collection authorities, String idTokenValue, String accessTokenValue, String refreshTokenValue) { @@ -70,12 +70,12 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { this.refreshTokenValue = refreshTokenValue; this.serverConfiguration = null; // we don't need a server config anymore - + setAuthenticated(true); } /** - * Constructs OIDCAuthenticationToken for use as a data shuttle from the filter to the auth provider. + * Constructs OIDCAuthenticationToken for use as a data shuttle from the filter to the auth provider. * * Set to not-authenticated. * @@ -83,8 +83,8 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { * @param userId * @param idToken */ - public OIDCAuthenticationToken(String userId, String issuer, - ServerConfiguration serverConfiguration, + public OIDCAuthenticationToken(String userId, String issuer, + ServerConfiguration serverConfiguration, String idTokenValue, String accessTokenValue, String refreshTokenValue) { super(new ArrayList(0)); @@ -97,10 +97,10 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { this.refreshTokenValue = refreshTokenValue; this.userInfo = null; // we don't have a UserInfo yet - + this.serverConfiguration = serverConfiguration; - - + + setAuthenticated(false); } @@ -130,46 +130,46 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken { } /** - * @return the idTokenValue - */ - public String getIdTokenValue() { - return idTokenValue; - } + * @return the idTokenValue + */ + public String getIdTokenValue() { + return idTokenValue; + } /** - * @return the accessTokenValue - */ - public String getAccessTokenValue() { - return accessTokenValue; - } + * @return the accessTokenValue + */ + public String getAccessTokenValue() { + return accessTokenValue; + } /** - * @return the refreshTokenValue - */ - public String getRefreshTokenValue() { - return refreshTokenValue; - } + * @return the refreshTokenValue + */ + public String getRefreshTokenValue() { + return refreshTokenValue; + } /** - * @return the serverConfiguration - */ - public ServerConfiguration getServerConfiguration() { - return serverConfiguration; - } + * @return the serverConfiguration + */ + public ServerConfiguration getServerConfiguration() { + return serverConfiguration; + } /** - * @return the issuer - */ - public String getIssuer() { - return issuer; - } + * @return the issuer + */ + public String getIssuer() { + return issuer; + } /** - * @return the userInfo - */ - public UserInfo getUserInfo() { - return userInfo; - } - - + * @return the userInfo + */ + public UserInfo getUserInfo() { + return userInfo; + } + + } \ No newline at end of file diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java index c2a1c210a..76f4fbce4 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/UserInfoFetcher.java @@ -15,7 +15,7 @@ import com.google.gson.JsonParser; public class UserInfoFetcher { public UserInfo loadUserInfo(OIDCAuthenticationToken token) { - + HttpClient httpClient = new DefaultHttpClient(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); @@ -25,15 +25,15 @@ public class UserInfoFetcher { MultiValueMap form = new LinkedMultiValueMap(); form.add("access_token", token.getAccessTokenValue()); form.add("schema", "openid"); - + String userInfoString = restTemplate.postForObject(token.getServerConfiguration().getUserInfoUri(), form, String.class); - + JsonObject userInfoJson = new JsonParser().parse(userInfoString).getAsJsonObject(); - + UserInfo userInfo = DefaultUserInfo.fromJson(userInfoJson); - + return userInfo; - - } + + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisher.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisher.java index 11d415473..86198b40d 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisher.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisher.java @@ -34,16 +34,16 @@ public class ClientKeyPublisher implements BeanDefinitionRegistryPostProcessor { /** * If either the jwkPublishUrl or x509PublishUrl fields are set on this bean, set up a listener on that URL to publish keys. - */ - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + */ + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (!Strings.isNullOrEmpty(getJwkPublishUrl())) { // add a mapping to this class BeanDefinitionBuilder clientKeyMapping = BeanDefinitionBuilder.rootBeanDefinition(ClientKeyPublisherMapping.class); // custom view resolver BeanDefinitionBuilder viewResolver = BeanDefinitionBuilder.rootBeanDefinition(JwkViewResolver.class); - + if (!Strings.isNullOrEmpty(getJwkPublishUrl())) { clientKeyMapping.addPropertyValue("jwkPublishUrl", getJwkPublishUrl()); @@ -56,49 +56,49 @@ public class ClientKeyPublisher implements BeanDefinitionRegistryPostProcessor { registry.registerBeanDefinition("jwkKeyList", jwkView.getBeanDefinition()); viewResolver.addPropertyReference("jwk", "jwkKeyList"); } - + registry.registerBeanDefinition("clientKeyMapping", clientKeyMapping.getBeanDefinition()); registry.registerBeanDefinition("jwkViewResolver", viewResolver.getBeanDefinition()); - + } - - } + + } /* (non-Javadoc) - * @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry) - */ - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + * @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry) + */ + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { this.registry = registry; - } + } /** - * Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set. - * @return - */ + * Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set. + * @return + */ public ModelAndView publishClientJwk() { - + // map from key id to key Map keys = signingAndValidationService.getAllPublicKeys(); // TODO: check if keys are empty, return a 404 here or just an empty list? - + return new ModelAndView(jwkViewName, "keys", keys); } /** - * @return the jwkPublishUrl - */ - public String getJwkPublishUrl() { - return jwkPublishUrl; - } + * @return the jwkPublishUrl + */ + public String getJwkPublishUrl() { + return jwkPublishUrl; + } /** - * @param jwkPublishUrl the jwkPublishUrl to set - */ - public void setJwkPublishUrl(String jwkPublishUrl) { - this.jwkPublishUrl = jwkPublishUrl; - } + * @param jwkPublishUrl the jwkPublishUrl to set + */ + public void setJwkPublishUrl(String jwkPublishUrl) { + this.jwkPublishUrl = jwkPublishUrl; + } /** * @return the signingAndValidationService diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisherMapping.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisherMapping.java index b8682135a..eae8a4c0b 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisherMapping.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/ClientKeyPublisherMapping.java @@ -19,72 +19,72 @@ public class ClientKeyPublisherMapping extends RequestMappingInfoHandlerMapping private String jwkPublishUrl; private String x509PublishUrl; - + /* (non-Javadoc) - * @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#isHandler(java.lang.Class) - */ - @Override - protected boolean isHandler(Class beanType) { - return beanType.equals(ClientKeyPublisher.class); - } + * @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#isHandler(java.lang.Class) + */ + @Override + protected boolean isHandler(Class beanType) { + return beanType.equals(ClientKeyPublisher.class); + } /** * Map the "jwkKeyPublish" method to our jwkPublishUrl. * Map the "x509KeyPublish" method to our x509PublishUrl. - */ - @Override - protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { - - if (method.getName().equals("publishClientJwk") && getJwkPublishUrl() != null) { - return new RequestMappingInfo( - new PatternsRequestCondition(new String[] {getJwkPublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false), - null, - null, - null, - null, - null, - null); - } else if (method.getName().equals("publishClientx509") && getX509PublishUrl() != null) { - return new RequestMappingInfo( - new PatternsRequestCondition(new String[] {getX509PublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false), - null, - null, - null, - null, - null, - null); - } else { - return null; - } - - } + */ + @Override + protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { + + if (method.getName().equals("publishClientJwk") && getJwkPublishUrl() != null) { + return new RequestMappingInfo( + new PatternsRequestCondition(new String[] {getJwkPublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false), + null, + null, + null, + null, + null, + null); + } else if (method.getName().equals("publishClientx509") && getX509PublishUrl() != null) { + return new RequestMappingInfo( + new PatternsRequestCondition(new String[] {getX509PublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false), + null, + null, + null, + null, + null, + null); + } else { + return null; + } + + } /** - * @return the jwkPublishUrl - */ - public String getJwkPublishUrl() { - return jwkPublishUrl; - } + * @return the jwkPublishUrl + */ + public String getJwkPublishUrl() { + return jwkPublishUrl; + } /** - * @param jwkPublishUrl the jwkPublishUrl to set - */ - public void setJwkPublishUrl(String jwkPublishUrl) { - this.jwkPublishUrl = jwkPublishUrl; - } + * @param jwkPublishUrl the jwkPublishUrl to set + */ + public void setJwkPublishUrl(String jwkPublishUrl) { + this.jwkPublishUrl = jwkPublishUrl; + } /** - * @return the x509PublishUrl - */ - public String getX509PublishUrl() { - return x509PublishUrl; - } + * @return the x509PublishUrl + */ + public String getX509PublishUrl() { + return x509PublishUrl; + } /** - * @param x509PublishUrl the x509PublishUrl to set - */ - public void setX509PublishUrl(String x509PublishUrl) { - this.x509PublishUrl = x509PublishUrl; - } + * @param x509PublishUrl the x509PublishUrl to set + */ + public void setX509PublishUrl(String x509PublishUrl) { + this.x509PublishUrl = x509PublishUrl; + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/JwkViewResolver.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/JwkViewResolver.java index 06443b8cf..d72b06a26 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/JwkViewResolver.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/keypublisher/JwkViewResolver.java @@ -20,12 +20,12 @@ public class JwkViewResolver implements ViewResolver, Ordered { private String jwkViewName = "jwkKeyList"; private View jwk; - + private String x509ViewName = "x509certs"; private View x509; - + private int order = HIGHEST_PRECEDENCE; // highest precedence, most specific -- avoids hitting the catch-all view resolvers - + /** * Map "jwkKeyList" to the jwk property and "x509certs" to the x509 property on this bean. * Everything else returns null @@ -46,74 +46,74 @@ public class JwkViewResolver implements ViewResolver, Ordered { } /** - * @return the x509 - */ - public View getX509() { - return x509; - } + * @return the x509 + */ + public View getX509() { + return x509; + } /** - * @param x509 the x509 to set - */ - public void setX509(View x509) { - this.x509 = x509; - } + * @param x509 the x509 to set + */ + public void setX509(View x509) { + this.x509 = x509; + } /** - * @return the jwk - */ - public View getJwk() { - return jwk; - } + * @return the jwk + */ + public View getJwk() { + return jwk; + } /** - * @param jwk the jwk to set - */ - public void setJwk(View jwk) { - this.jwk = jwk; - } + * @param jwk the jwk to set + */ + public void setJwk(View jwk) { + this.jwk = jwk; + } /** - * @return the order - */ - @Override - public int getOrder() { - return order; - } + * @return the order + */ + @Override + public int getOrder() { + return order; + } /** - * @param order the order to set - */ - public void setOrder(int order) { - this.order = order; - } + * @param order the order to set + */ + public void setOrder(int order) { + this.order = order; + } /** - * @return the jwkViewName - */ - public String getJwkViewName() { - return jwkViewName; - } + * @return the jwkViewName + */ + public String getJwkViewName() { + return jwkViewName; + } /** - * @param jwkViewName the jwkViewName to set - */ - public void setJwkViewName(String jwkViewName) { - this.jwkViewName = jwkViewName; - } + * @param jwkViewName the jwkViewName to set + */ + public void setJwkViewName(String jwkViewName) { + this.jwkViewName = jwkViewName; + } /** - * @return the x509ViewName - */ - public String getX509ViewName() { - return x509ViewName; - } + * @return the x509ViewName + */ + public String getX509ViewName() { + return x509ViewName; + } /** - * @param x509ViewName the x509ViewName to set - */ - public void setX509ViewName(String x509ViewName) { - this.x509ViewName = x509ViewName; - } + * @param x509ViewName the x509ViewName to set + */ + public void setX509ViewName(String x509ViewName) { + this.x509ViewName = x509ViewName; + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/model/IssuerServiceResponse.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/model/IssuerServiceResponse.java index 338ebb442..aecb9f4db 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/model/IssuerServiceResponse.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/model/IssuerServiceResponse.java @@ -16,24 +16,24 @@ public class IssuerServiceResponse { private String loginHint; private String targetLinkUri; private String redirectUrl; - + /** * @param issuer * @param loginHint * @param targetLinkUri */ - public IssuerServiceResponse(String issuer, String loginHint, String targetLinkUri) { - this.issuer = issuer; - this.loginHint = loginHint; - this.targetLinkUri = targetLinkUri; - } - + public IssuerServiceResponse(String issuer, String loginHint, String targetLinkUri) { + this.issuer = issuer; + this.loginHint = loginHint; + this.targetLinkUri = targetLinkUri; + } + /** * @param redirectUrl */ - public IssuerServiceResponse(String redirectUrl) { - this.redirectUrl = redirectUrl; - } + public IssuerServiceResponse(String redirectUrl) { + this.redirectUrl = redirectUrl; + } /** * @return the issuer */ @@ -82,12 +82,12 @@ public class IssuerServiceResponse { public void setRedirectUrl(String redirectUrl) { this.redirectUrl = redirectUrl; } - + /** * If the redirect url has been set, then we should send a redirect using it instead of processing things. */ public boolean shouldRedirect() { return this.redirectUrl != null; } - + } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/AuthRequestUrlBuilder.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/AuthRequestUrlBuilder.java index b34b07192..690a78a01 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/AuthRequestUrlBuilder.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/AuthRequestUrlBuilder.java @@ -20,6 +20,6 @@ public interface AuthRequestUrlBuilder { * @param state * @return */ - public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state); - + public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state); + } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ClientConfigurationService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ClientConfigurationService.java index cd4404eac..5508cbb20 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ClientConfigurationService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ClientConfigurationService.java @@ -12,5 +12,5 @@ import org.springframework.security.oauth2.provider.ClientDetails; public interface ClientConfigurationService { public ClientDetails getClientConfiguration(String issuer); - + } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/IssuerService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/IssuerService.java index c755e4e1e..d979a342f 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/IssuerService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/IssuerService.java @@ -17,5 +17,5 @@ import org.mitre.openid.connect.client.model.IssuerServiceResponse; public interface IssuerService { public IssuerServiceResponse getIssuer(HttpServletRequest request); - + } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ServerConfigurationService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ServerConfigurationService.java index a18fad2ae..4b415810f 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ServerConfigurationService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/ServerConfigurationService.java @@ -12,5 +12,5 @@ import org.mitre.openid.connect.config.ServerConfiguration; public interface ServerConfigurationService { public ServerConfiguration getServerConfiguration(String issuer); - + } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/PlainAuthRequestUrlBuilder.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/PlainAuthRequestUrlBuilder.java index e63fcc5f8..15457a37f 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/PlainAuthRequestUrlBuilder.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/PlainAuthRequestUrlBuilder.java @@ -28,7 +28,7 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder { @Override public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state) { try { - + URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri()); uriBuilder.addParameter("response_type", "code"); uriBuilder.addParameter("client_id", clientConfig.getClientId()); @@ -39,20 +39,20 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder { uriBuilder.addParameter("nonce", nonce); uriBuilder.addParameter("state", state); - + // Optional parameters: // TODO: display, prompt - - return uriBuilder.build().toString(); - - } catch (URISyntaxException e) { - throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e); - - } - - + return uriBuilder.build().toString(); + + } catch (URISyntaxException e) { + throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e); + + } + + + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/SignedAuthRequestUrlBuilder.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/SignedAuthRequestUrlBuilder.java index d9d5efb1a..fb707e869 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/SignedAuthRequestUrlBuilder.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/SignedAuthRequestUrlBuilder.java @@ -4,11 +4,6 @@ package org.mitre.openid.connect.client.service.impl; import java.net.URISyntaxException; -import java.security.NoSuchAlgorithmException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.apache.http.client.utils.URIBuilder; import org.mitre.jwt.signer.service.JwtSigningAndValidationService; @@ -38,34 +33,34 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder { // create our signed JWT for the request object JWTClaimsSet claims = new JWTClaimsSet(); - + //set parameters to JwtClaims claims.setCustomClaim("response_type", "code"); claims.setCustomClaim("client_id", clientConfig.getClientId()); claims.setCustomClaim("scope", Joiner.on(" ").join(clientConfig.getScope())); - + // build our redirect URI claims.setCustomClaim("redirect_uri", redirectUri); - + // this comes back in the id token claims.setCustomClaim("nonce", nonce); - + // this comes back in the auth request return claims.setCustomClaim("state", state); - + SignedJWT jwt = new SignedJWT(new JWSHeader(signingAndValidationService.getDefaultSigningAlgorithm()), claims); - + signingAndValidationService.signJwt(jwt); - + try { - URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri()); - uriBuilder.addParameter("request", jwt.serialize()); - - // build out the URI - return uriBuilder.build().toString(); - } catch (URISyntaxException e) { - throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e); - } + URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri()); + uriBuilder.addParameter("request", jwt.serialize()); + + // build out the URI + return uriBuilder.build().toString(); + } catch (URISyntaxException e) { + throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e); + } } /** diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticClientConfigurationService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticClientConfigurationService.java index e765f27b0..6a2da7b08 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticClientConfigurationService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticClientConfigurationService.java @@ -21,7 +21,7 @@ public class StaticClientConfigurationService implements ClientConfigurationServ // Map of issuer URL -> client configuration information private Map clients; - + /** * @return the clients */ @@ -43,19 +43,19 @@ public class StaticClientConfigurationService implements ClientConfigurationServ */ @Override public ClientDetails getClientConfiguration(String issuer) { - + return clients.get(issuer); } /* (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ - @Override - public void afterPropertiesSet() throws Exception { - if (clients == null || clients.isEmpty()) { - throw new IllegalArgumentException("Clients map cannot be null or empty"); - } - - } + @Override + public void afterPropertiesSet() throws Exception { + if (clients == null || clients.isEmpty()) { + throw new IllegalArgumentException("Clients map cannot be null or empty"); + } + + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticServerConfigurationService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticServerConfigurationService.java index 3276b7f63..9d3f6b1fb 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticServerConfigurationService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticServerConfigurationService.java @@ -45,12 +45,12 @@ public class StaticServerConfigurationService implements ServerConfigurationServ /* (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ - @Override - public void afterPropertiesSet() throws Exception { - if (servers == null || servers.isEmpty()) { - throw new IllegalArgumentException("Servers map cannot be null or empty."); - } - - } + @Override + public void afterPropertiesSet() throws Exception { + if (servers == null || servers.isEmpty()) { + throw new IllegalArgumentException("Servers map cannot be null or empty."); + } + + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticSingleIssuerService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticSingleIssuerService.java index 908b439dd..108fd2eb9 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticSingleIssuerService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/StaticSingleIssuerService.java @@ -16,7 +16,7 @@ import com.google.common.base.Strings; * */ public class StaticSingleIssuerService implements IssuerService, InitializingBean { - + private String issuer; /** @@ -46,13 +46,13 @@ public class StaticSingleIssuerService implements IssuerService, InitializingBea /* (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ - @Override - public void afterPropertiesSet() throws Exception { + @Override + public void afterPropertiesSet() throws Exception { - if (Strings.isNullOrEmpty(issuer)) { - throw new IllegalArgumentException("Issuer must not be null or empty."); - } - - } + if (Strings.isNullOrEmpty(issuer)) { + throw new IllegalArgumentException("Issuer must not be null or empty."); + } + + } } diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/ThirdPartyIssuerService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/ThirdPartyIssuerService.java index 18addcd04..dc7532baa 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/ThirdPartyIssuerService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/ThirdPartyIssuerService.java @@ -25,34 +25,34 @@ import com.google.common.base.Strings; public class ThirdPartyIssuerService implements IssuerService, InitializingBean { private String accountChooserUrl; - + /* (non-Javadoc) * @see org.mitre.openid.connect.client.service.IssuerService#getIssuer(javax.servlet.http.HttpServletRequest) */ @Override public IssuerServiceResponse getIssuer(HttpServletRequest request) { - + // if the issuer is passed in, return that if (!Strings.isNullOrEmpty(request.getParameter("iss"))) { return new IssuerServiceResponse(request.getParameter("iss"), request.getParameter("login_hint"), request.getParameter("target_link_uri")); } else { - + try { // otherwise, need to forward to the account chooser String redirectUri = request.getRequestURL().toString(); - URIBuilder builder = new URIBuilder(accountChooserUrl); - - builder.addParameter("redirect_uri", redirectUri); - - return new IssuerServiceResponse(builder.build().toString()); - - } catch (URISyntaxException e) { - throw new AuthenticationServiceException("Account Chooser URL is not valid", e); - } - - + URIBuilder builder = new URIBuilder(accountChooserUrl); + + builder.addParameter("redirect_uri", redirectUri); + + return new IssuerServiceResponse(builder.build().toString()); + + } catch (URISyntaxException e) { + throw new AuthenticationServiceException("Account Chooser URL is not valid", e); + } + + } - + } /** @@ -72,12 +72,12 @@ public class ThirdPartyIssuerService implements IssuerService, InitializingBean /* (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ - @Override - public void afterPropertiesSet() throws Exception { - if (Strings.isNullOrEmpty(this.accountChooserUrl)) { - throw new IllegalArgumentException("Account Chooser URL cannot be null or empty"); - } - - } + @Override + public void afterPropertiesSet() throws Exception { + if (Strings.isNullOrEmpty(this.accountChooserUrl)) { + throw new IllegalArgumentException("Account Chooser URL cannot be null or empty"); + } + + } } diff --git a/openid-connect-client/src/test/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilterTest.java b/openid-connect-client/src/test/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilterTest.java index db9994c59..efa1dcf19 100644 --- a/openid-connect-client/src/test/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilterTest.java +++ b/openid-connect-client/src/test/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilterTest.java @@ -1,10 +1,5 @@ package org.mitre.openid.connect.client; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * Unit test for OIDCAuthenticationFilter @@ -18,10 +13,10 @@ public class AbstractOIDCAuthenticationFilterTest { //@Autowired private OIDCAuthenticationFilter filter; - + //@Test public void testUrlConstruction() { - + } /** @@ -37,7 +32,7 @@ public class AbstractOIDCAuthenticationFilterTest { public void setFilter(OIDCAuthenticationFilter filter) { this.filter = filter; } - - - + + + } diff --git a/openid-connect-common/src/main/java/org/mitre/jose/JWEAlgorithmEmbed.java b/openid-connect-common/src/main/java/org/mitre/jose/JWEAlgorithmEmbed.java index 4081d515b..deeebceeb 100644 --- a/openid-connect-common/src/main/java/org/mitre/jose/JWEAlgorithmEmbed.java +++ b/openid-connect-common/src/main/java/org/mitre/jose/JWEAlgorithmEmbed.java @@ -5,7 +5,6 @@ package org.mitre.jose; import javax.persistence.Basic; import javax.persistence.Embeddable; -import javax.persistence.Entity; import javax.persistence.Transient; import com.google.common.base.Strings; @@ -22,16 +21,16 @@ import com.nimbusds.jose.JWEAlgorithm; public class JWEAlgorithmEmbed { public static final JWEAlgorithmEmbed NONE = getForAlgorithmName("none"); - + private JWEAlgorithm algorithm; public JWEAlgorithmEmbed() { - + } - + public JWEAlgorithmEmbed(JWEAlgorithm algorithm) { - this.algorithm = algorithm; - } + this.algorithm = algorithm; + } public static JWEAlgorithmEmbed getForAlgorithmName (String algorithmName) { JWEAlgorithmEmbed ent = new JWEAlgorithmEmbed(); @@ -42,7 +41,7 @@ public class JWEAlgorithmEmbed { return ent; } } - + /** * Get the name of this algorithm, return null if no algorithm set. * @return @@ -55,9 +54,9 @@ public class JWEAlgorithmEmbed { return null; } } - + /** - * Set the name of this algorithm. + * Set the name of this algorithm. * Calls JWEAlgorithm.parse() * @param algorithmName */ @@ -72,15 +71,15 @@ public class JWEAlgorithmEmbed { /* (non-Javadoc) * @see java.lang.Object#toString() */ - @Override - public String toString() { - return "JWEAlgorithmEmbed [algorithm=" + algorithm + "]"; - } + @Override + public String toString() { + return "JWEAlgorithmEmbed [algorithm=" + algorithm + "]"; + } /** * @return the algorithm */ - @Transient + @Transient public JWEAlgorithm getAlgorithm() { return algorithm; } @@ -91,5 +90,5 @@ public class JWEAlgorithmEmbed { public void setAlgorithm(JWEAlgorithm algorithm) { this.algorithm = algorithm; } - + } diff --git a/openid-connect-common/src/main/java/org/mitre/jose/JWEEncryptionMethodEmbed.java b/openid-connect-common/src/main/java/org/mitre/jose/JWEEncryptionMethodEmbed.java index bcd2f40b8..1b6b17cfb 100644 --- a/openid-connect-common/src/main/java/org/mitre/jose/JWEEncryptionMethodEmbed.java +++ b/openid-connect-common/src/main/java/org/mitre/jose/JWEEncryptionMethodEmbed.java @@ -9,7 +9,6 @@ import javax.persistence.Transient; import com.google.common.base.Strings; import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; /** * @author jricher @@ -19,16 +18,16 @@ import com.nimbusds.jose.JWEAlgorithm; public class JWEEncryptionMethodEmbed { public static final JWEEncryptionMethodEmbed NONE = getForAlgorithmName("none"); - + private EncryptionMethod algorithm; public JWEEncryptionMethodEmbed() { - + } - + public JWEEncryptionMethodEmbed(EncryptionMethod algorithm) { - this.algorithm = algorithm; - } + this.algorithm = algorithm; + } public static JWEEncryptionMethodEmbed getForAlgorithmName (String algorithmName) { JWEEncryptionMethodEmbed ent = new JWEEncryptionMethodEmbed(); @@ -39,7 +38,7 @@ public class JWEEncryptionMethodEmbed { return ent; } } - + /** * Get the name of this algorithm, return null if no algorithm set. * @return @@ -52,9 +51,9 @@ public class JWEEncryptionMethodEmbed { return null; } } - + /** - * Set the name of this algorithm. + * Set the name of this algorithm. * Calls EncryptionMethod.parse() * @param algorithmName */ @@ -69,15 +68,15 @@ public class JWEEncryptionMethodEmbed { /* (non-Javadoc) * @see java.lang.Object#toString() */ - @Override - public String toString() { - return "JWEEncryptionMethodEmbed [algorithm=" + algorithm + "]"; - } + @Override + public String toString() { + return "JWEEncryptionMethodEmbed [algorithm=" + algorithm + "]"; + } /** * @return the algorithm */ - @Transient + @Transient public EncryptionMethod getAlgorithm() { return algorithm; } @@ -88,6 +87,6 @@ public class JWEEncryptionMethodEmbed { public void setAlgorithm(EncryptionMethod algorithm) { this.algorithm = algorithm; } - + } diff --git a/openid-connect-common/src/main/java/org/mitre/jose/JWSAlgorithmEmbed.java b/openid-connect-common/src/main/java/org/mitre/jose/JWSAlgorithmEmbed.java index e9aff0cc0..276768a50 100644 --- a/openid-connect-common/src/main/java/org/mitre/jose/JWSAlgorithmEmbed.java +++ b/openid-connect-common/src/main/java/org/mitre/jose/JWSAlgorithmEmbed.java @@ -5,8 +5,6 @@ package org.mitre.jose; import javax.persistence.Basic; import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.Id; import javax.persistence.Transient; import com.google.common.base.Strings; @@ -23,17 +21,17 @@ import com.nimbusds.jose.JWSAlgorithm; public class JWSAlgorithmEmbed { public static final JWSAlgorithmEmbed NONE = getForAlgorithmName("none"); - + private JWSAlgorithm algorithm; - - public JWSAlgorithmEmbed() { - + + public JWSAlgorithmEmbed() { + } public JWSAlgorithmEmbed(JWSAlgorithm algorithm) { - this.algorithm = algorithm; - } - + this.algorithm = algorithm; + } + public static JWSAlgorithmEmbed getForAlgorithmName (String algorithmName) { JWSAlgorithmEmbed ent = new JWSAlgorithmEmbed(); ent.setAlgorithmName(algorithmName); @@ -56,9 +54,9 @@ public class JWSAlgorithmEmbed { return null; } } - + /** - * Set the name of this algorithm. + * Set the name of this algorithm. * Calls JWSAlgorithm.parse() * @param algorithmName */ @@ -88,11 +86,11 @@ public class JWSAlgorithmEmbed { /* (non-Javadoc) * @see java.lang.Object#toString() */ - @Override - public String toString() { - return "JWSAlgorithmEmbed [algorithm=" + algorithm + "]"; - } + @Override + public String toString() { + return "JWSAlgorithmEmbed [algorithm=" + algorithm + "]"; + } + + - - } diff --git a/openid-connect-common/src/main/java/org/mitre/jose/keystore/JWKSetKeyStore.java b/openid-connect-common/src/main/java/org/mitre/jose/keystore/JWKSetKeyStore.java index b70cc2ab2..a4a4cfdcd 100644 --- a/openid-connect-common/src/main/java/org/mitre/jose/keystore/JWKSetKeyStore.java +++ b/openid-connect-common/src/main/java/org/mitre/jose/keystore/JWKSetKeyStore.java @@ -21,26 +21,26 @@ import com.nimbusds.jose.jwk.JWKSet; public class JWKSetKeyStore implements InitializingBean { private JWKSet jwkSet; - + private Resource location; - + public JWKSetKeyStore() { - + } - + public JWKSetKeyStore(JWKSet jwkSet) { this.jwkSet = jwkSet; } - + /* (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @Override public void afterPropertiesSet() throws Exception { - + if (jwkSet == null) { if (location != null) { - + if (location.exists() && location.isReadable()) { // read in the file from disk @@ -48,11 +48,11 @@ public class JWKSetKeyStore implements InitializingBean { // parse it into a jwkSet object jwkSet = JWKSet.parse(s); - + } else { throw new IllegalArgumentException("Key Set resource could not be read: " + location); } - + } else { throw new IllegalArgumentException("Key store must be initialized with at least one of a jwkSet or a location."); } @@ -90,10 +90,10 @@ public class JWKSetKeyStore implements InitializingBean { /** * Get the list of keys in this keystore. This is a passthrough to the underlying JWK Set */ - public List getKeys() { - return jwkSet.getKeys(); - } - - + public List getKeys() { + return jwkSet.getKeys(); + } + + } diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java index dcf63ae93..d95ac01bf 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java @@ -16,7 +16,6 @@ package org.mitre.jwt.signer.service; import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; import java.util.Map; import com.nimbusds.jose.JWSAlgorithm; @@ -29,7 +28,7 @@ public interface JwtSigningAndValidationService { * Get all public keys for this service, mapped by their Key ID */ public Map getAllPublicKeys(); - + /** * Checks the signature of the given JWT against all configured signers, * returns true if at least one of the signers validates it. @@ -37,17 +36,17 @@ public interface JwtSigningAndValidationService { * @param jwtString * the string representation of the JWT as sent on the wire * @return true if the signature is valid, false if not - * @throws NoSuchAlgorithmException + * @throws NoSuchAlgorithmException */ public boolean validateSignature(SignedJWT jwtString); - + /** * Called to sign a jwt in place for a client that hasn't registered a preferred signing algorithm. * Use the default algorithm to sign. * * @param jwt the jwt to sign * @return the signed jwt - * @throws NoSuchAlgorithmException + * @throws NoSuchAlgorithmException */ public void signJwt(SignedJWT jwt); @@ -55,7 +54,7 @@ public interface JwtSigningAndValidationService { * Get the default signing algorithm for use when nothing else has been specified. * @return */ - public JWSAlgorithm getDefaultSigningAlgorithm(); + public JWSAlgorithm getDefaultSigningAlgorithm(); /** * Sign a jwt using the selected algorithm. The algorithm is selected using the String parameter values specified @@ -67,7 +66,7 @@ public interface JwtSigningAndValidationService { */ //TODO: implement later; only need signJwt(Jwt jwt) for now //public Jwt signJwt(Jwt jwt, String alg); - + /** * TODO: method to sign a jwt using a specified algorithm and a key id */ diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java index b9cdaff66..8bc89a688 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java @@ -52,9 +52,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid private static Logger logger = LoggerFactory.getLogger(DefaultJwtSigningAndValidationService.class); private String defaultSignerKeyId; - + private JWSAlgorithm defaultAlgorithm; - + // map of identifier to key private Map keys = new HashMap(); @@ -70,10 +70,10 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid * @throws NoSuchAlgorithmException * If there is no appropriate algorithm to tie the keys to. */ - public DefaultJwtSigningAndValidationService(Map keys) throws NoSuchAlgorithmException, InvalidKeySpecException { - this.keys = keys; - buildSignersAndVerifiers(); - } + public DefaultJwtSigningAndValidationService(Map keys) throws NoSuchAlgorithmException, InvalidKeySpecException { + this.keys = keys; + buildSignersAndVerifiers(); + } /** * Build this service based on the given keystore. All keys must have a key @@ -87,18 +87,18 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid * @throws NoSuchAlgorithmException * If there is no appropriate algorithm to tie the keys to. */ - public DefaultJwtSigningAndValidationService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException { - // convert all keys in the keystore to a map based on key id - for (JWK key : keyStore.getKeys()) { - if (!Strings.isNullOrEmpty(key.getKeyID())) { - this.keys.put(key.getKeyID(), key); - } else { - throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key); - } - } - buildSignersAndVerifiers(); - } - + public DefaultJwtSigningAndValidationService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException { + // convert all keys in the keystore to a map based on key id + for (JWK key : keyStore.getKeys()) { + if (!Strings.isNullOrEmpty(key.getKeyID())) { + this.keys.put(key.getKeyID(), key); + } else { + throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key); + } + } + buildSignersAndVerifiers(); + } + /** * @return the defaultSignerKeyId */ @@ -117,22 +117,22 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid * @return */ @Override - public JWSAlgorithm getDefaultSigningAlgorithm() { - return defaultAlgorithm; - } - - public void setDefaultSigningAlgorithmName(String algName) { - defaultAlgorithm = JWSAlgorithm.parse(algName); - } - - public String getDefaultSigningAlgorithmName() { - if (defaultAlgorithm != null) { - return defaultAlgorithm.getName(); - } else { - return null; - } - } - + public JWSAlgorithm getDefaultSigningAlgorithm() { + return defaultAlgorithm; + } + + public void setDefaultSigningAlgorithmName(String algName) { + defaultAlgorithm = JWSAlgorithm.parse(algName); + } + + public String getDefaultSigningAlgorithmName() { + if (defaultAlgorithm != null) { + return defaultAlgorithm.getName(); + } else { + return null; + } + } + /* * (non-Javadoc) * @@ -145,9 +145,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid if (keys == null) { throw new IllegalArgumentException("Signing and validation service must have at least one key configured."); } - + buildSignersAndVerifiers(); - + logger.info("DefaultJwtSigningAndValidationService is ready: " + this.toString()); } @@ -156,45 +156,45 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid * @throws InvalidKeySpecException If the keys in the JWKs are not valid * @throws NoSuchAlgorithmException If there is no appropriate algorithm to tie the keys to. */ - private void buildSignersAndVerifiers() throws NoSuchAlgorithmException, InvalidKeySpecException { + private void buildSignersAndVerifiers() throws NoSuchAlgorithmException, InvalidKeySpecException { for (Map.Entry jwkEntry : keys.entrySet()) { String id = jwkEntry.getKey(); JWK jwk = jwkEntry.getValue(); - - if (jwk instanceof RSAKey) { - // build RSA signers & verifiers - - if (jwk.isPrivate()) { // only add the signer if there's a private key - RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey()); - signers.put(id, signer); - } - - RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey()); - verifiers.put(id, verifier); - - } else if (jwk instanceof ECKey) { - // build EC signers & verifiers - - // TODO: add support for EC keys - logger.warn("EC Keys are not yet supported."); - - } else if (jwk instanceof OctetSequenceKey) { - // build HMAC signers & verifiers - - if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private - MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray()); - signers.put(id, signer); - } - - MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray()); - verifiers.put(id, verifier); - - } else { - logger.warn("Unknown key type: " + jwk); - } - } - } + + if (jwk instanceof RSAKey) { + // build RSA signers & verifiers + + if (jwk.isPrivate()) { // only add the signer if there's a private key + RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey()); + signers.put(id, signer); + } + + RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey()); + verifiers.put(id, verifier); + + } else if (jwk instanceof ECKey) { + // build EC signers & verifiers + + // TODO: add support for EC keys + logger.warn("EC Keys are not yet supported."); + + } else if (jwk instanceof OctetSequenceKey) { + // build HMAC signers & verifiers + + if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private + MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray()); + signers.put(id, signer); + } + + MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray()); + verifiers.put(id, verifier); + + } else { + logger.warn("Unknown key type: " + jwk); + } + } + } /** * Sign a jwt in place using the configured default signer. @@ -204,18 +204,18 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid if (getDefaultSignerKeyId() == null) { throw new IllegalStateException("Tried to call default signing with no default signer ID set"); } - + JWSSigner signer = signers.get(getDefaultSignerKeyId()); try { - jwt.sign(signer); - } catch (JOSEException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - + jwt.sign(signer); + } catch (JOSEException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } - + @Override public boolean validateSignature(SignedJWT jwt) { @@ -225,9 +225,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid return true; } } catch (JOSEException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + // TODO Auto-generated catch block + e.printStackTrace(); + } } return false; } @@ -235,17 +235,17 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid @Override public Map getAllPublicKeys() { Map pubKeys = new HashMap(); - + // pull all keys out of the verifiers if we know how for (String keyId : keys.keySet()) { - JWK key = keys.get(keyId); - JWK pub = key.toPublicJWK(); - if (pub != null) { - pubKeys.put(keyId, pub); - } - } - + JWK key = keys.get(keyId); + JWK pub = key.toPublicJWK(); + if (pub != null) { + pubKeys.put(keyId, pub); + } + } + return pubKeys; } - + } diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetSigningAndValidationServiceCacheService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetSigningAndValidationServiceCacheService.java index 608ea6441..8f4a09ea5 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetSigningAndValidationServiceCacheService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetSigningAndValidationServiceCacheService.java @@ -3,12 +3,6 @@ */ package org.mitre.jwt.signer.service.impl; -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.RSAPublicKeySpec; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.ExecutionException; import org.apache.http.client.HttpClient; @@ -22,16 +16,11 @@ import org.springframework.web.client.RestTemplate; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; -import com.nimbusds.jose.JWSVerifier; -import com.nimbusds.jose.crypto.RSASSAVerifier; -import com.nimbusds.jose.jwk.JWK; import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jose.jwk.KeyType; -import com.nimbusds.jose.jwk.RSAKey; /** * - * Creates a + * Creates a * * @author jricher * @@ -46,49 +35,49 @@ public class JWKSetSigningAndValidationServiceCacheService { .maximumSize(100) .build(new JWKSetVerifierFetcher()); } - + /** * @param key * @return * @throws ExecutionException * @see com.google.common.cache.Cache#get(java.lang.Object) */ - public JwtSigningAndValidationService get(String key) { - try { - return cache.get(key); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } - } + public JwtSigningAndValidationService get(String key) { + try { + return cache.get(key); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } /** - * @author jricher - * - */ - private class JWKSetVerifierFetcher extends CacheLoader { - private HttpClient httpClient = new DefaultHttpClient(); - private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient); - private RestTemplate restTemplate = new RestTemplate(httpFactory); - - /** - * Load the JWK Set and build the appropriate signing service. - */ - @Override - public JwtSigningAndValidationService load(String key) throws Exception { + * @author jricher + * + */ + private class JWKSetVerifierFetcher extends CacheLoader { + private HttpClient httpClient = new DefaultHttpClient(); + private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + private RestTemplate restTemplate = new RestTemplate(httpFactory); - String jsonString = restTemplate.getForObject(key, String.class); - JWKSet jwkSet = JWKSet.parse(jsonString); - - JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet); - - JwtSigningAndValidationService service = new DefaultJwtSigningAndValidationService(keyStore); + /** + * Load the JWK Set and build the appropriate signing service. + */ + @Override + public JwtSigningAndValidationService load(String key) throws Exception { - return service; - - } + String jsonString = restTemplate.getForObject(key, String.class); + JWKSet jwkSet = JWKSet.parse(jsonString); - } + JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet); + + JwtSigningAndValidationService service = new DefaultJwtSigningAndValidationService(keyStore); + + return service; + + } + + } } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthenticationHolderEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthenticationHolderEntity.java index 28d408deb..f9bcf5a40 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthenticationHolderEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthenticationHolderEntity.java @@ -22,13 +22,13 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; public class AuthenticationHolderEntity { private Long id; - + private Long ownerId; - + private OAuth2Authentication authentication; - + public AuthenticationHolderEntity() { - + } @Id @@ -60,7 +60,7 @@ public class AuthenticationHolderEntity { public void setAuthentication(OAuth2Authentication authentication) { this.authentication = authentication; } - - - + + + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java index 23cb53a97..96b7431ad 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java @@ -28,18 +28,18 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; public class AuthorizationCodeEntity { private Long id; - + private String code; - + private OAuth2Authentication authentication; /** * Default constructor. */ public AuthorizationCodeEntity() { - + } - + /** * Create a new AuthorizationCodeEntity with the given code and AuthorizationRequestHolder. * @@ -50,12 +50,12 @@ public class AuthorizationCodeEntity { this.code = code; this.authentication = authRequest; } - + /** * @return the id */ @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } @@ -98,5 +98,5 @@ public class AuthorizationCodeEntity { public void setAuthentication(OAuth2Authentication authentication) { this.authentication = authentication; } - + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/ClientDetailsEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/ClientDetailsEntity.java index 0f6eed0d2..f39af57c0 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/ClientDetailsEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/ClientDetailsEntity.java @@ -67,7 +67,7 @@ public class ClientDetailsEntity implements ClientDetails { private static final long serialVersionUID = -1617727085733786296L; private Long id; - + /** Fields from the OAuth2 Dynamic Registration Specification */ private String clientId = null; // client_id private String clientSecret = null; // client_secret @@ -75,7 +75,7 @@ public class ClientDetailsEntity implements ClientDetails { private String clientName; // client_name private String clientUri; // client_uri private String logoUri; // logo_uri - private Set contacts; // contacts + private Set contacts; // contacts private String tosUri; // tos_uri private AuthMethod tokenEndpointAuthMethod = AuthMethod.SECRET_BASIC; // token_endpoint_auth_method private Set scope = new HashSet(); // scope @@ -83,38 +83,38 @@ public class ClientDetailsEntity implements ClientDetails { private Set responseTypes = new HashSet(); // response_types private String policyUri; private String jwksUri; - - /** Fields from OIDC Client Registration Specification **/ + + /** Fields from OIDC Client Registration Specification **/ private AppType applicationType; // application_type private String sectorIdentifierUri; // sector_identifier_uri private SubjectType subjectType; // subject_type - + private JWSAlgorithmEmbed requestObjectSigningAlg = JWSAlgorithmEmbed.NONE; // request_object_signing_alg - + private JWSAlgorithmEmbed userInfoSignedResponseAlg = JWSAlgorithmEmbed.NONE; // user_info_signed_response_alg private JWEAlgorithmEmbed userInfoEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // user_info_encrypted_response_alg private JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // user_info_encrypted_response_enc - + private JWSAlgorithmEmbed idTokenSignedResponseAlg = JWSAlgorithmEmbed.NONE; // id_token_signed_response_alg private JWEAlgorithmEmbed idTokenEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // id_token_encrypted_response_alg private JWEEncryptionMethodEmbed idTokenEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // id_token_encrypted_response_enc - + private Integer defaultMaxAge; // default_max_age private Boolean requireAuthTime; // require_auth_time private Set defaultACRvalues; // default_acr_values - + private String initiateLoginUri; // initiate_login_uri private String postLogoutRedirectUri; // post_logout_redirect_uri - + private Set requestUris; // request_uris - + /** Fields to support the ClientDetails interface **/ private Set authorities = new HashSet(); - private Integer accessTokenValiditySeconds = 0; // in seconds - private Integer refreshTokenValiditySeconds = 0; // in seconds + private Integer accessTokenValiditySeconds = 0; // in seconds + private Integer refreshTokenValiditySeconds = 0; // in seconds private Set resourceIds = new HashSet(); private Map additionalInformation = new HashMap(); - + /** Our own fields **/ private String clientDescription = ""; // human-readable description private boolean reuseRefreshToken = true; // do we let someone reuse a refresh token? @@ -122,16 +122,16 @@ public class ClientDetailsEntity implements ClientDetails { private boolean allowIntrospection = false; // do we let this client call the introspection endpoint? private Integer idTokenValiditySeconds; //timeout for id tokens private Date createdAt; // time the client was created - + public enum AuthMethod { - SECRET_POST("client_secret_post"), - SECRET_BASIC("client_secret_basic"), - SECRET_JWT("client_secret_jwt"), - PRIVATE_KEY("private_key_jwt"), + SECRET_POST("client_secret_post"), + SECRET_BASIC("client_secret_basic"), + SECRET_JWT("client_secret_jwt"), + PRIVATE_KEY("private_key_jwt"), NONE("none"); - + private final String value; - + // map to aid reverse lookup private static final Map lookup = new HashMap(); static { @@ -139,77 +139,77 @@ public class ClientDetailsEntity implements ClientDetails { lookup.put(a.getValue(), a); } } - + AuthMethod(String value) { this.value = value; } - + public String getValue() { return value; } - + public static AuthMethod getByValue(String value) { return lookup.get(value); } } - + public enum AppType { WEB("web"), NATIVE("native"); - + private final String value; - - // map to aid reverse lookup + + // map to aid reverse lookup private static final Map lookup = new HashMap(); static { for (AppType a : AppType.values()) { - lookup.put(a.getValue(), a); - } + lookup.put(a.getValue(), a); + } } - + AppType(String value) { this.value = value; } - + public String getValue() { return value; } - + public static AppType getByValue(String value) { return lookup.get(value); } } - - public enum SubjectType { - PAIRWISE("pairwise"), PUBLIC("public"); + + public enum SubjectType { + PAIRWISE("pairwise"), PUBLIC("public"); private final String value; - - // map to aid reverse lookup + + // map to aid reverse lookup private static final Map lookup = new HashMap(); static { for (SubjectType u : SubjectType.values()) { - lookup.put(u.getValue(), u); - } + lookup.put(u.getValue(), u); + } } - + SubjectType(String value) { this.value = value; } - + public String getValue() { return value; } - + public static SubjectType getByValue(String value) { return lookup.get(value); } - } + } /** * Create a blank ClientDetailsEntity */ public ClientDetailsEntity() { - + } /** @@ -228,34 +228,34 @@ public class ClientDetailsEntity implements ClientDetails { public void setId(Long id) { this.id = id; } - + /** - * @return the clientDescription - */ + * @return the clientDescription + */ @Basic @Column(name="client_description") - public String getClientDescription() { - return clientDescription; - } + public String getClientDescription() { + return clientDescription; + } /** - * @param clientDescription Human-readable long description of the client (optional) - */ - public void setClientDescription(String clientDescription) { - this.clientDescription = clientDescription; - } + * @param clientDescription Human-readable long description of the client (optional) + */ + public void setClientDescription(String clientDescription) { + this.clientDescription = clientDescription; + } /** - * @return the allowRefresh - */ + * @return the allowRefresh + */ @Transient - public boolean isAllowRefresh() { + public boolean isAllowRefresh() { if (grantTypes != null) { return getAuthorizedGrantTypes().contains("refresh_token"); } else { return false; // if there are no grants, we can't be refreshing them, can we? } - } + } @Basic @Column(name="reuse_refresh_tokens") @@ -266,7 +266,7 @@ public class ClientDetailsEntity implements ClientDetails { public void setReuseRefreshToken(boolean reuseRefreshToken) { this.reuseRefreshToken = reuseRefreshToken; } - + /** * @return the idTokenValiditySeconds */ @@ -282,7 +282,7 @@ public class ClientDetailsEntity implements ClientDetails { public void setIdTokenValiditySeconds(Integer idTokenValiditySeconds) { this.idTokenValiditySeconds = idTokenValiditySeconds; } - + /** * @return the dynamicallyRegistered */ @@ -298,148 +298,149 @@ public class ClientDetailsEntity implements ClientDetails { public void setDynamicallyRegistered(boolean dynamicallyRegistered) { this.dynamicallyRegistered = dynamicallyRegistered; } - - - + + + /** - * @return the allowIntrospection - */ + * @return the allowIntrospection + */ @Basic @Column(name="allow_introspection") - public boolean isAllowIntrospection() { - return allowIntrospection; - } + public boolean isAllowIntrospection() { + return allowIntrospection; + } /** - * @param allowIntrospection the allowIntrospection to set - */ - public void setAllowIntrospection(boolean allowIntrospection) { - this.allowIntrospection = allowIntrospection; - } + * @param allowIntrospection the allowIntrospection to set + */ + public void setAllowIntrospection(boolean allowIntrospection) { + this.allowIntrospection = allowIntrospection; + } /** * - */ - @Override - @Transient - public boolean isSecretRequired() { - // TODO: this should check the auth method field instead - return getClientSecret() != null; - } + */ + @Override + @Transient + public boolean isSecretRequired() { + // TODO: this should check the auth method field instead + return getClientSecret() != null; + } /** * If the scope list is not null or empty, then this client has been scoped. - */ - @Override - @Transient - public boolean isScoped() { - return getScope() != null && !getScope().isEmpty(); - } - + */ + @Override + @Transient + public boolean isScoped() { + return getScope() != null && !getScope().isEmpty(); + } + /** - * @return the clientId - */ + * @return the clientId + */ @Basic @Override @Column(name="client_id") - public String getClientId() { - return clientId; - } + public String getClientId() { + return clientId; + } /** - * @param clientId The OAuth2 client_id, must be unique to this client - */ - public void setClientId(String clientId) { - this.clientId = clientId; - } + * @param clientId The OAuth2 client_id, must be unique to this client + */ + public void setClientId(String clientId) { + this.clientId = clientId; + } /** - * @return the clientSecret - */ + * @return the clientSecret + */ @Basic @Override @Column(name="client_secret") public String getClientSecret() { - return clientSecret; - } + return clientSecret; + } /** - * @param clientSecret the OAuth2 client_secret (optional) - */ - public void setClientSecret(String clientSecret) { - this.clientSecret = clientSecret; - } + * @param clientSecret the OAuth2 client_secret (optional) + */ + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } /** - * @return the scope - */ + * @return the scope + */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable( name="client_scope", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Override @Column(name="scope") public Set getScope() { - return scope; - } + return scope; + } /** - * @param scope the set of scopes allowed to be issued to this client - */ - public void setScope(Set scope) { - this.scope = scope; - } + * @param scope the set of scopes allowed to be issued to this client + */ + public void setScope(Set scope) { + this.scope = scope; + } /** - * @return the authorizedGrantTypes - */ + * @return the authorizedGrantTypes + */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable( name="client_grant_type", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Column(name="grant_type") public Set getGrantTypes() { - return grantTypes; - } + return grantTypes; + } /** - * @param authorizedGrantTypes the OAuth2 grant types that this client is allowed to use - */ - public void setGrantTypes(Set grantTypes) { - this.grantTypes = grantTypes; - } + * @param authorizedGrantTypes the OAuth2 grant types that this client is allowed to use + */ + public void setGrantTypes(Set grantTypes) { + this.grantTypes = grantTypes; + } - /** - * passthrough for SECOAUTH api - */ - public Set getAuthorizedGrantTypes() { - return getGrantTypes(); - } - /** - * @return the authorities - */ + * passthrough for SECOAUTH api + */ + @Override + public Set getAuthorizedGrantTypes() { + return getGrantTypes(); + } + + /** + * @return the authorities + */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable( name="client_authority", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Override @Column(name="authority") - public Set getAuthorities() { - return authorities; - } + public Set getAuthorities() { + return authorities; + } /** - * @param authorities the Spring Security authorities this client is given - */ - public void setAuthorities(Set authorities) { - this.authorities = authorities; - } + * @param authorities the Spring Security authorities this client is given + */ + public void setAuthorities(Set authorities) { + this.authorities = authorities; + } @Override @Basic @@ -447,13 +448,13 @@ public class ClientDetailsEntity implements ClientDetails { public Integer getAccessTokenValiditySeconds() { return accessTokenValiditySeconds; } - + /** - * @param accessTokenTimeout the accessTokenTimeout to set - */ - public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) { - this.accessTokenValiditySeconds = accessTokenValiditySeconds; - } + * @param accessTokenTimeout the accessTokenTimeout to set + */ + public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) { + this.accessTokenValiditySeconds = accessTokenValiditySeconds; + } @Override @Basic @@ -461,64 +462,65 @@ public class ClientDetailsEntity implements ClientDetails { public Integer getRefreshTokenValiditySeconds() { return refreshTokenValiditySeconds; } - + /** - * @param refreshTokenTimeout Lifetime of refresh tokens, in seconds (optional - leave null for no timeout) - */ - public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) { - this.refreshTokenValiditySeconds = refreshTokenValiditySeconds; - } - - /** - * @return the registeredRedirectUri - */ - @ElementCollection(fetch = FetchType.EAGER) + * @param refreshTokenTimeout Lifetime of refresh tokens, in seconds (optional - leave null for no timeout) + */ + public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) { + this.refreshTokenValiditySeconds = refreshTokenValiditySeconds; + } + + /** + * @return the registeredRedirectUri + */ + @ElementCollection(fetch = FetchType.EAGER) @CollectionTable( name="client_redirect_uri", joinColumns=@JoinColumn(name="owner_id") - ) - @Column(name="redirect_uri") - public Set getRedirectUris() { - return redirectUris; - } + ) + @Column(name="redirect_uri") + public Set getRedirectUris() { + return redirectUris; + } /** - * @param registeredRedirectUri the registeredRedirectUri to set - */ - public void setRedirectUris(Set redirectUris) { - this.redirectUris = redirectUris; - } + * @param registeredRedirectUri the registeredRedirectUri to set + */ + public void setRedirectUris(Set redirectUris) { + this.redirectUris = redirectUris; + } - /** - * Pass-through method to fulfill the ClientDetails interface with a bad name - */ - @Override - @Transient - public Set getRegisteredRedirectUri() { - return getRedirectUris(); - } - /** - * @return the resourceIds - */ + * Pass-through method to fulfill the ClientDetails interface with a bad name + */ + @Override + @Transient + public Set getRegisteredRedirectUri() { + return getRedirectUris(); + } + + /** + * @return the resourceIds + */ + @Override @ElementCollection(fetch = FetchType.EAGER) @CollectionTable( name="client_resource", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Column(name="resource_id") - public Set getResourceIds() { - return resourceIds; - } + public Set getResourceIds() { + return resourceIds; + } /** - * @param resourceIds the resourceIds to set - */ - public void setResourceIds(Set resourceIds) { - this.resourceIds = resourceIds; - } + * @param resourceIds the resourceIds to set + */ + public void setResourceIds(Set resourceIds) { + this.resourceIds = resourceIds; + } + - /** * This library does not make use of this field, so it is not * stored using our persistence layer. @@ -533,7 +535,7 @@ public class ClientDetailsEntity implements ClientDetails { return this.additionalInformation; } - + @Enumerated(EnumType.STRING) @@ -580,7 +582,7 @@ public class ClientDetailsEntity implements ClientDetails { @CollectionTable( name="client_contact", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Column(name="contact") public Set getContacts() { return contacts; @@ -599,7 +601,7 @@ public class ClientDetailsEntity implements ClientDetails { public void setLogoUri(String logoUri) { this.logoUri = logoUri; } - + @Basic @Column(name="policy_uri") public String getPolicyUri() { @@ -611,36 +613,36 @@ public class ClientDetailsEntity implements ClientDetails { } /** - * @return the clientUrl - */ + * @return the clientUrl + */ @Basic @Column(name="client_uri") - public String getClientUri() { - return clientUri; - } + public String getClientUri() { + return clientUri; + } /** - * @param clientUrl the clientUrl to set - */ - public void setClientUri(String clientUri) { - this.clientUri = clientUri; - } + * @param clientUrl the clientUrl to set + */ + public void setClientUri(String clientUri) { + this.clientUri = clientUri; + } /** - * @return the tosUrl - */ - @Basic - @Column(name="tos_uri") - public String getTosUri() { - return tosUri; - } + * @return the tosUrl + */ + @Basic + @Column(name="tos_uri") + public String getTosUri() { + return tosUri; + } /** - * @param tosUrl the tosUrl to set - */ - public void setTosUri(String tosUri) { - this.tosUri = tosUri; - } + * @param tosUrl the tosUrl to set + */ + public void setTosUri(String tosUri) { + this.tosUri = tosUri; + } @Basic @Column(name="jwks_uri") @@ -708,7 +710,7 @@ public class ClientDetailsEntity implements ClientDetails { public void setUserInfoEncryptedResponseEnc(JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc) { this.userInfoEncryptedResponseEnc = userInfoEncryptedResponseEnc; - } + } @Embedded @AttributeOverrides({ @@ -773,7 +775,7 @@ public class ClientDetailsEntity implements ClientDetails { @CollectionTable( name="client_response_type", joinColumns=@JoinColumn(name="response_type") - ) + ) @Column(name="response_type") public Set getResponseTypes() { return responseTypes; @@ -793,7 +795,7 @@ public class ClientDetailsEntity implements ClientDetails { @CollectionTable( name="client_default_acr_value", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Column(name="default_acr_value") public Set getDefaultACRvalues() { return defaultACRvalues; @@ -845,7 +847,7 @@ public class ClientDetailsEntity implements ClientDetails { @CollectionTable( name="client_request_uri", joinColumns=@JoinColumn(name="owner_id") - ) + ) @Column(name="request_uri") public Set getRequestUris() { return requestUris; @@ -863,15 +865,15 @@ public class ClientDetailsEntity implements ClientDetails { */ @Temporal(TemporalType.TIMESTAMP) @Column(name="created_at") - public Date getCreatedAt() { - return createdAt; - } + public Date getCreatedAt() { + return createdAt; + } /** * @param createdAt the createdAt to set */ - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java index 75b7eef24..f35d98b50 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java @@ -71,17 +71,17 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { public static final String REGISTRATION_TOKEN_SCOPE = "registration-token"; public static String ID_TOKEN = "id_token"; - + private Long id; - + private ClientDetailsEntity client; - + private AuthenticationHolderEntity authenticationHolder; // the authentication that made this access - + private JWT jwtValue; // JWT-encoded access token value - + private OAuth2AccessTokenEntity idToken; // JWT-encoded OpenID Connect IdToken - + private Date expiration; private String tokenType = OAuth2AccessToken.BEARER_TYPE; @@ -89,14 +89,14 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { private OAuth2RefreshTokenEntity refreshToken; private Set scope; - + /** * Create a new, blank access token */ public OAuth2AccessTokenEntity() { } - + /** * @return the id */ @@ -114,8 +114,9 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { } /** - * Get all additional information to be sent to the serializer. Inserts a copy of the IdToken (in JWT String form). + * Get all additional information to be sent to the serializer. Inserts a copy of the IdToken (in JWT String form). */ + @Override @Transient public Map getAdditionalInformation() { Map map = new HashMap(); //super.getAdditionalInformation(); @@ -124,121 +125,127 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { } return map; } - + /** * The authentication in place when this token was created. - * @return the authentication - */ + * @return the authentication + */ @ManyToOne @JoinColumn(name = "auth_holder_id") - public AuthenticationHolderEntity getAuthenticationHolder() { - return authenticationHolder; - } + public AuthenticationHolderEntity getAuthenticationHolder() { + return authenticationHolder; + } /** - * @param authentication the authentication to set - */ - public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { - this.authenticationHolder = authenticationHolder; - } + * @param authentication the authentication to set + */ + public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { + this.authenticationHolder = authenticationHolder; + } /** - * @return the client - */ + * @return the client + */ @ManyToOne @JoinColumn(name = "client_id") - public ClientDetailsEntity getClient() { - return client; - } + public ClientDetailsEntity getClient() { + return client; + } /** - * @param client the client to set - */ - public void setClient(ClientDetailsEntity client) { - this.client = client; - } - - /** - * Get the string-encoded value of this access token. - */ - @Basic - @Column(name="token_value") - public String getValue() { + * @param client the client to set + */ + public void setClient(ClientDetailsEntity client) { + this.client = client; + } + + /** + * Get the string-encoded value of this access token. + */ + @Override + @Basic + @Column(name="token_value") + public String getValue() { return jwtValue.serialize(); - } + } - /** - * Set the "value" of this Access Token - * - * @param value the JWT string - * @throws ParseException if "value" is not a properly formatted JWT string - */ - public void setValue(String value) throws ParseException { + /** + * Set the "value" of this Access Token + * + * @param value the JWT string + * @throws ParseException if "value" is not a properly formatted JWT string + */ + public void setValue(String value) throws ParseException { setJwt(JWTParser.parse(value)); - } + } - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - public Date getExpiration() { - return expiration; - } + @Override + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + public Date getExpiration() { + return expiration; + } - public void setExpiration(Date expiration) { - this.expiration = expiration; - } + public void setExpiration(Date expiration) { + this.expiration = expiration; + } - @Basic - @Column(name="token_type") - public String getTokenType() { - return tokenType; - } + @Override + @Basic + @Column(name="token_type") + public String getTokenType() { + return tokenType; + } - public void setTokenType(String tokenType) { - this.tokenType = tokenType; - } + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } - @ManyToOne - @JoinColumn(name="refresh_token_id") - public OAuth2RefreshTokenEntity getRefreshToken() { - return refreshToken; - } + @Override + @ManyToOne + @JoinColumn(name="refresh_token_id") + public OAuth2RefreshTokenEntity getRefreshToken() { + return refreshToken; + } - public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) { - this.refreshToken = refreshToken; - } + public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) { + this.refreshToken = refreshToken; + } - public void setRefreshToken(OAuth2RefreshToken refreshToken) { - if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) { - // TODO: make a copy constructor instead.... - throw new IllegalArgumentException("Not a storable refresh token entity!"); - } - // force a pass through to the entity version - setRefreshToken((OAuth2RefreshTokenEntity)refreshToken); - } - - @ElementCollection(fetch=FetchType.EAGER) - @CollectionTable( - joinColumns=@JoinColumn(name="owner_id"), - name="token_scope" - ) - public Set getScope() { - return scope; - } + public void setRefreshToken(OAuth2RefreshToken refreshToken) { + if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) { + // TODO: make a copy constructor instead.... + throw new IllegalArgumentException("Not a storable refresh token entity!"); + } + // force a pass through to the entity version + setRefreshToken((OAuth2RefreshTokenEntity)refreshToken); + } - public void setScope(Set scope) { - this.scope = scope; - } + @Override + @ElementCollection(fetch=FetchType.EAGER) + @CollectionTable( + joinColumns=@JoinColumn(name="owner_id"), + name="token_scope" + ) + public Set getScope() { + return scope; + } - @Transient + public void setScope(Set scope) { + this.scope = scope; + } + + @Override + @Transient public boolean isExpired() { return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); } - + /** * @return the idToken */ - @OneToOne(cascade=CascadeType.ALL) // one-to-one mapping for now - @JoinColumn(name = "id_token_id") + @OneToOne(cascade=CascadeType.ALL) // one-to-one mapping for now + @JoinColumn(name = "id_token_id") public OAuth2AccessTokenEntity getIdToken() { return idToken; } @@ -249,7 +256,7 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { public void setIdToken(OAuth2AccessTokenEntity idToken) { this.idToken = idToken; } - + /** * @return the idTokenString */ diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java index d4b80aea2..fbbae47e7 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java @@ -39,9 +39,7 @@ import javax.persistence.Transient; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; -import com.nimbusds.jwt.PlainJWT; /** * @author jricher @@ -58,14 +56,14 @@ import com.nimbusds.jwt.PlainJWT; public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken { private Long id; - + private AuthenticationHolderEntity authenticationHolder; - + private ClientDetailsEntity client; //JWT-encoded representation of this access token entity private JWT jwt; - + // our refresh tokens might expire private Date expiration; @@ -91,97 +89,98 @@ public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken { public void setId(Long id) { this.id = id; } - - /** - * The authentication in place when the original access token was - * created - * - * @return the authentication - */ - @ManyToOne - @JoinColumn(name = "auth_holder_id") - public AuthenticationHolderEntity getAuthenticationHolder() { - return authenticationHolder; - } /** - * @param authentication the authentication to set - */ - public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { - this.authenticationHolder = authenticationHolder; - } + * The authentication in place when the original access token was + * created + * + * @return the authentication + */ + @ManyToOne + @JoinColumn(name = "auth_holder_id") + public AuthenticationHolderEntity getAuthenticationHolder() { + return authenticationHolder; + } + + /** + * @param authentication the authentication to set + */ + public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { + this.authenticationHolder = authenticationHolder; + } /** * Get the JWT-encoded value of this token */ - @Basic - @Column(name="token_value") - public String getValue() { - return jwt.serialize(); - } + @Override + @Basic + @Column(name="token_value") + public String getValue() { + return jwt.serialize(); + } - /** - * Set the value of this token as a string. Parses the string into a JWT. - * @param value - * @throws ParseException if the value is not a valid JWT string - */ - public void setValue(String value) throws ParseException { - setJwt(JWTParser.parse(value)); - } + /** + * Set the value of this token as a string. Parses the string into a JWT. + * @param value + * @throws ParseException if the value is not a valid JWT string + */ + public void setValue(String value) throws ParseException { + setJwt(JWTParser.parse(value)); + } - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - public Date getExpiration() { - return expiration; - } + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + public Date getExpiration() { + return expiration; + } /* (non-Javadoc) - * @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date) - */ - - public void setExpiration(Date expiration) { - this.expiration = expiration; - } + * @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date) + */ - /** - * Has this token expired? - * @return true if it has a timeout set and the timeout has passed - */ - @Transient + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + + /** + * Has this token expired? + * @return true if it has a timeout set and the timeout has passed + */ + @Transient public boolean isExpired() { return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); } - + /** - * @return the client - */ + * @return the client + */ @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "client_id") - public ClientDetailsEntity getClient() { - return client; - } + public ClientDetailsEntity getClient() { + return client; + } /** - * @param client the client to set - */ - public void setClient(ClientDetailsEntity client) { - this.client = client; - } + * @param client the client to set + */ + public void setClient(ClientDetailsEntity client) { + this.client = client; + } + + /** + * Get the JWT object directly + * @return the jwt + */ + @Transient + public JWT getJwt() { + return jwt; + } + + /** + * @param jwt the jwt to set + */ + public void setJwt(JWT jwt) { + this.jwt = jwt; + } - /** - * Get the JWT object directly - * @return the jwt - */ - @Transient - public JWT getJwt() { - return jwt; - } - - /** - * @param jwt the jwt to set - */ - public void setJwt(JWT jwt) { - this.jwt = jwt; - } - } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java index fff8505e2..a2dd93ce6 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java @@ -28,7 +28,7 @@ public class SystemScope { private Long id; private String value; // scope value private String description; // human-readable description - private String icon; // class of the icon to display on the auth page + private String icon; // class of the icon to display on the auth page private boolean allowDynReg = false; // can a dynamically registered client ask for this scope? private boolean defaultScope = false; // is this a default scope for newly-registered clients? @@ -36,16 +36,16 @@ public class SystemScope { * Make a blank system scope with no value */ public SystemScope() { - + } - + /** * Make a system scope with the given scope value * @param value */ - public SystemScope(String value) { - this.value = value; - } + public SystemScope(String value) { + this.value = value; + } /** * @return the id */ @@ -117,7 +117,7 @@ public class SystemScope { public void setAllowDynReg(boolean allowDynReg) { this.allowDynReg = allowDynReg; } - + /** * @return the defaultScope */ @@ -136,71 +136,71 @@ public class SystemScope { /* (non-Javadoc) * @see java.lang.Object#hashCode() */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (allowDynReg ? 1231 : 1237); - result = prime * result + (defaultScope ? 1231 : 1237); - result = prime * result + ((description == null) ? 0 : description.hashCode()); - result = prime * result + ((icon == null) ? 0 : icon.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (allowDynReg ? 1231 : 1237); + result = prime * result + (defaultScope ? 1231 : 1237); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((icon == null) ? 0 : icon.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - SystemScope other = (SystemScope) obj; - if (allowDynReg != other.allowDynReg) { - return false; - } - if (defaultScope != other.defaultScope) { - return false; - } - if (description == null) { - if (other.description != null) { - return false; - } - } else if (!description.equals(other.description)) { - return false; - } - if (icon == null) { - if (other.icon != null) { - return false; - } - } else if (!icon.equals(other.icon)) { - return false; - } - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (value == null) { - if (other.value != null) { - return false; - } - } else if (!value.equals(other.value)) { - return false; - } - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SystemScope other = (SystemScope) obj; + if (allowDynReg != other.allowDynReg) { + return false; + } + if (defaultScope != other.defaultScope) { + return false; + } + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (icon == null) { + if (other.icon != null) { + return false; + } + } else if (!icon.equals(other.icon)) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (value == null) { + if (other.value != null) { + return false; + } + } else if (!value.equals(other.value)) { + return false; + } + return true; + } + + - - } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java index fcf0ac18a..310e3f66b 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java @@ -6,13 +6,13 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; public interface AuthenticationHolderRepository { public AuthenticationHolderEntity getById(Long id); - + public AuthenticationHolderEntity getByAuthentication(OAuth2Authentication a); - + public void removeById(Long id); - + public void remove(AuthenticationHolderEntity a); - + public AuthenticationHolderEntity save(AuthenticationHolderEntity a); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java index 63c6b2e8b..0883c3967 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java @@ -5,7 +5,7 @@ import org.springframework.security.oauth2.common.exceptions.InvalidGrantExcepti import org.springframework.security.oauth2.provider.OAuth2Authentication; /** - * Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys. + * Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys. * * @author aanganes * @@ -19,14 +19,14 @@ public interface AuthorizationCodeRepository { * @return the saved AuthorizationCodeEntity */ public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode); - + /** * Consume an authorization code. * * @param code the authorization code value - * @return the authentication associated with the code + * @return the authentication associated with the code * @throws InvalidGrantException if no AuthorizationCodeEntity is found with the given value */ public OAuth2Authentication consume(String code) throws InvalidGrantException; - + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2ClientRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2ClientRepository.java index 6e958da8f..6242daeae 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2ClientRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2ClientRepository.java @@ -20,7 +20,7 @@ import java.util.Collection; import org.mitre.oauth2.model.ClientDetailsEntity; public interface OAuth2ClientRepository { - + public ClientDetailsEntity getById(Long id); public ClientDetailsEntity getClientByClientId(String clientId); diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java index b5b1622ce..b1a5b994f 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java @@ -27,17 +27,17 @@ public interface OAuth2TokenRepository { public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token); public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue); - + public OAuth2RefreshTokenEntity getRefreshTokenById(Long Id); public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken); public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken); - + public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue); - + public OAuth2AccessTokenEntity getAccessTokenById(Long id); public void removeAccessToken(OAuth2AccessTokenEntity accessToken); @@ -55,8 +55,8 @@ public interface OAuth2TokenRepository { public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth); /** - * @return - */ - public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken); - + * @return + */ + public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken); + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/SystemScopeRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/SystemScopeRepository.java index a7ff78e5f..acc5a4a73 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/SystemScopeRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/SystemScopeRepository.java @@ -14,13 +14,13 @@ import org.mitre.oauth2.model.SystemScope; public interface SystemScopeRepository { public Set getAll(); - + public SystemScope getById(Long id); - + public SystemScope getByValue(String value); - + public void remove(SystemScope scope); - + public SystemScope save(SystemScope scope); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java index 8dff09bda..48c355e65 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java @@ -24,19 +24,20 @@ import org.springframework.security.oauth2.provider.ClientDetailsService; public interface ClientDetailsEntityService extends ClientDetailsService { public ClientDetailsEntity saveNewClient(ClientDetailsEntity client); - + public ClientDetailsEntity getClientById(Long id); - + + @Override public ClientDetailsEntity loadClientByClientId(String clientId) throws OAuth2Exception; public void deleteClient(ClientDetailsEntity client); - + public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient); public Collection getAllClients(); public ClientDetailsEntity generateClientId(ClientDetailsEntity client); - + public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java index 1780a5c17..60cbcbbed 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java @@ -26,32 +26,34 @@ import org.springframework.security.oauth2.provider.token.ResourceServerTokenSer public interface OAuth2TokenEntityService extends AuthorizationServerTokenServices, ResourceServerTokenServices { + @Override public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue); - + public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue); public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken); public void revokeAccessToken(OAuth2AccessTokenEntity accessToken); - + public List getAccessTokensForClient(ClientDetailsEntity client); - + public List getRefreshTokensForClient(ClientDetailsEntity client); public void clearExpiredTokens(); - + public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken); - + public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); - + + @Override public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication); - + public OAuth2AccessTokenEntity getAccessTokenById(Long id); /** - * @param incomingToken - * @return - */ - public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken); - + * @param incomingToken + * @return + */ + public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken); + } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java index 22883c066..e33842314 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java @@ -12,15 +12,15 @@ import org.mitre.oauth2.model.SystemScope; * */ public interface SystemScopeService { - + public Set getAll(); - + /** * Get all scopes that are defaulted to new clients on this system * @return */ public Set getDefaults(); - + /** * Get all scopes that are allowed for dynamic registration on this system * @return @@ -28,20 +28,20 @@ public interface SystemScopeService { public Set getDynReg(); public SystemScope getById(Long id); - + public SystemScope getByValue(String value); - + public void remove(SystemScope scope); - + public SystemScope save(SystemScope scope); - + /** * Translate the set of scope strings into a set of SystemScope objects. * @param scope * @return */ public Set fromStrings(Set scope); - + /** * Pluck the scope values from the set of SystemScope objects and return a list of strings * @param scope diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java index b1023f2a5..7791a410c 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java @@ -17,7 +17,6 @@ package org.mitre.oauth2.service.impl; import java.util.ArrayList; import java.util.Collection; -import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; @@ -44,32 +43,32 @@ public class DefaultClientUserDetailsService implements UserDetailsService { private ClientDetailsService clientDetailsService; @Override - public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException { + public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException { ClientDetails client = clientDetailsService.loadClientByClientId(clientId); - + if (client != null) { - - String password = client.getClientSecret(); - boolean enabled = true; - boolean accountNonExpired = true; - boolean credentialsNonExpired = true; - boolean accountNonLocked = true; - Collection authorities = client.getAuthorities(); - if (authorities == null || authorities.isEmpty()) { - // automatically inject ROLE_CLIENT if none exists ... - // TODO: this should probably happen on the client service side instead to keep it in the real data model - authorities = new ArrayList(); - GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT"); - authorities.add(roleClient); - } - - return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + + String password = client.getClientSecret(); + boolean enabled = true; + boolean accountNonExpired = true; + boolean credentialsNonExpired = true; + boolean accountNonLocked = true; + Collection authorities = client.getAuthorities(); + if (authorities == null || authorities.isEmpty()) { + // automatically inject ROLE_CLIENT if none exists ... + // TODO: this should probably happen on the client service side instead to keep it in the real data model + authorities = new ArrayList(); + GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT"); + authorities.add(roleClient); + } + + return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); } else { throw new UsernameNotFoundException("Client not found: " + clientId); } - } + } public ClientDetailsService getClientDetailsService() { return clientDetailsService; @@ -78,5 +77,5 @@ public class DefaultClientUserDetailsService implements UserDetailsService { public void setClientDetailsService(ClientDetailsService clientDetailsService) { this.clientDetailsService = clientDetailsService; } - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ConfigurationPropertiesBean.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ConfigurationPropertiesBean.java index 3f8c1a98e..e4fed7e9b 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ConfigurationPropertiesBean.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ConfigurationPropertiesBean.java @@ -20,7 +20,7 @@ package org.mitre.openid.connect.config; /** * Bean to hold configuration information that must be injected into various parts * of our application. Set all of the properties here, and autowire a reference - * to this bean if you need access to any configuration properties. + * to this bean if you need access to any configuration properties. * * @author AANGANES * @@ -28,22 +28,22 @@ package org.mitre.openid.connect.config; public class ConfigurationPropertiesBean { private String issuer; - + private String topbarTitle; - + private String logoImageUrl; - + public ConfigurationPropertiesBean() { } - + /** * @return the issuer baseUrl */ public String getIssuer() { return issuer; } - + /** * @param iss the issuer to set */ diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java index 0ad8f0e4b..d46ba4e8a 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/config/ServerConfiguration.java @@ -31,9 +31,9 @@ public class ServerConfiguration { private String tokenEndpointUri; private String issuer; - + private String jwksUri; - + private String userInfoUri; /** @@ -105,5 +105,5 @@ public class ServerConfiguration { public void setUserInfoUri(String userInfoUri) { this.userInfoUri = userInfoUri; } - + } \ No newline at end of file diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Address.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Address.java index c91311599..529aaac2d 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Address.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Address.java @@ -27,7 +27,7 @@ import javax.persistence.Table; @Table(name="address") public class Address { - + private Long id; private String formatted; private String streetAddress; @@ -35,14 +35,14 @@ public class Address { private String region; private String postalCode; private String country; - + /** * Empty constructor */ public Address() { - + } - + /** * @return the formatted address string */ @@ -125,19 +125,19 @@ public class Address { } /** - * @return the id - */ + * @return the id + */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) public Long getId() { - return id; - } + return id; + } /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } - + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java index f59938ddd..4ee6065d5 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java @@ -52,164 +52,164 @@ import com.google.common.collect.Sets; public class ApprovedSite { // unique id - private Long id; - - // which user made the approval + private Long id; + + // which user made the approval private String userId; - + // which OAuth2 client is this tied to private String clientId; - + // when was this first approved? private Date creationDate; - + // when was this last accessed? private Date accessDate; - + // if this is a time-limited access, when does it run out? private Date timeoutDate; - + // what scopes have been allowed // this should include all information for what data to access private Set allowedScopes; - + // If this AP is a WS, link to the WS private WhitelistedSite whitelistedSite; - + //Link to any access tokens approved through this stored decision private Set approvedAccessTokens = Sets.newHashSet(); - + /** * Empty constructor */ public ApprovedSite() { - } + } /** - * @return the id - */ + * @return the id + */ @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - public Long getId() { - return id; - } + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Long getId() { + return id; + } /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } /** - * @return the userInfo - */ - @Basic - @Column(name="user_id") - public String getUserId() { - return userId; - } + * @return the userInfo + */ + @Basic + @Column(name="user_id") + public String getUserId() { + return userId; + } /** - * @param userInfo the userInfo to set - */ - public void setUserId(String userId) { - this.userId = userId; - } + * @param userInfo the userInfo to set + */ + public void setUserId(String userId) { + this.userId = userId; + } /** - * @return the clientId - */ - @Basic - @Column(name="client_id") - public String getClientId() { - return clientId; - } + * @return the clientId + */ + @Basic + @Column(name="client_id") + public String getClientId() { + return clientId; + } /** - * @param clientId the clientId to set - */ - public void setClientId(String clientId) { - this.clientId = clientId; - } + * @param clientId the clientId to set + */ + public void setClientId(String clientId) { + this.clientId = clientId; + } /** - * @return the creationDate - */ - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - @Column(name="creation_date") - public Date getCreationDate() { - return creationDate; - } + * @return the creationDate + */ + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Column(name="creation_date") + public Date getCreationDate() { + return creationDate; + } /** - * @param creationDate the creationDate to set - */ - public void setCreationDate(Date creationDate) { - this.creationDate = creationDate; - } + * @param creationDate the creationDate to set + */ + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } /** - * @return the accessDate - */ - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - @Column(name="access_date") - public Date getAccessDate() { - return accessDate; - } + * @return the accessDate + */ + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Column(name="access_date") + public Date getAccessDate() { + return accessDate; + } /** - * @param accessDate the accessDate to set - */ - public void setAccessDate(Date accessDate) { - this.accessDate = accessDate; - } + * @param accessDate the accessDate to set + */ + public void setAccessDate(Date accessDate) { + this.accessDate = accessDate; + } /** - * @return the allowedScopes - */ - @ElementCollection(fetch = FetchType.EAGER) - @CollectionTable( - name="approved_site_scope", - joinColumns=@JoinColumn(name="owner_id") - ) - @Column(name="scope") - public Set getAllowedScopes() { - return allowedScopes; - } + * @return the allowedScopes + */ + @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable( + name="approved_site_scope", + joinColumns=@JoinColumn(name="owner_id") + ) + @Column(name="scope") + public Set getAllowedScopes() { + return allowedScopes; + } /** - * @param allowedScopes the allowedScopes to set - */ - public void setAllowedScopes(Set allowedScopes) { - this.allowedScopes = allowedScopes; - } + * @param allowedScopes the allowedScopes to set + */ + public void setAllowedScopes(Set allowedScopes) { + this.allowedScopes = allowedScopes; + } /** - * @return the timeoutDate - */ - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - @Column(name="timeout_date") - public Date getTimeoutDate() { - return timeoutDate; - } + * @return the timeoutDate + */ + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Column(name="timeout_date") + public Date getTimeoutDate() { + return timeoutDate; + } /** - * @param timeoutDate the timeoutDate to set - */ - public void setTimeoutDate(Date timeoutDate) { - this.timeoutDate = timeoutDate; - } + * @param timeoutDate the timeoutDate to set + */ + public void setTimeoutDate(Date timeoutDate) { + this.timeoutDate = timeoutDate; + } - /** - * Does this AP entry correspond to a WS? - * @return - */ - @Transient + /** + * Does this AP entry correspond to a WS? + * @return + */ + @Transient public Boolean getIsWhitelisted() { return (whitelistedSite != null); } @@ -227,10 +227,10 @@ public class ApprovedSite { /** * Has this approval expired? - * @return - */ + * @return + */ @Transient - public boolean isExpired() { + public boolean isExpired() { if (getTimeoutDate() != null) { Date now = new Date(); if (now.after(getTimeoutDate())) { @@ -241,7 +241,7 @@ public class ApprovedSite { } else { return false; } - } + } @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="approved_site_id") @@ -255,5 +255,5 @@ public class ApprovedSite { public void setApprovedAccessTokens(Set approvedAccessTokens) { this.approvedAccessTokens = approvedAccessTokens; } - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/BlacklistedSite.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/BlacklistedSite.java index 6baf5a895..59139fecf 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/BlacklistedSite.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/BlacklistedSite.java @@ -24,41 +24,41 @@ import javax.persistence.Table; }) public class BlacklistedSite { - // unique id - private Long id; - - // URI pattern to black list - private String uri; - - public BlacklistedSite() { - - } - + // unique id + private Long id; + + // URI pattern to black list + private String uri; + + public BlacklistedSite() { + + } + /** - * @return the id - */ + * @return the id + */ @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - public Long getId() { - return id; - } + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Long getId() { + return id; + } /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } - @Basic - @Column(name="uri") - public String getUri() { - return uri; - } + @Basic + @Column(name="uri") + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } - public void setUri(String uri) { - this.uri = uri; - } - } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java index b4212c58a..2d6c6dca4 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java @@ -33,21 +33,21 @@ import com.google.gson.JsonObject; @Table(name="user_info") @NamedQueries({ @NamedQuery(name="DefaultUserInfo.getAll", query = "select u from DefaultUserInfo u"), - @NamedQuery(name="DefaultUserInfo.getByUsername", query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :username"), - @NamedQuery(name="DefaultUserInfo.getBySubject", query = "select u from DefaultUserInfo u WHERE u.sub = :sub") + @NamedQuery(name="DefaultUserInfo.getByUsername", query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :username"), + @NamedQuery(name="DefaultUserInfo.getBySubject", query = "select u from DefaultUserInfo u WHERE u.sub = :sub") }) public class DefaultUserInfo implements UserInfo { - + private Long id; - private String sub; + private String sub; private String preferredUsername; - private String name; - private String givenName; - private String familyName; - private String middleName; - private String nickname; + private String name; + private String givenName; + private String familyName; + private String middleName; + private String nickname; private String profile; - private String picture; + private String picture; private String website; private String email; private Boolean emailVerified; @@ -58,8 +58,8 @@ public class DefaultUserInfo implements UserInfo { private Address address; private String updatedTime; private String birthdate; - - + + /** * @return the id */ @@ -356,21 +356,23 @@ public class DefaultUserInfo implements UserInfo { } /** - * @return the birthdate - */ + * @return the birthdate + */ + @Override @Basic @Column(name="birthdate") - public String getBirthdate() { - return birthdate; - } + public String getBirthdate() { + return birthdate; + } /** - * @param birthdate the birthdate to set - */ - public void setBirthdate(String birthdate) { - this.birthdate = birthdate; - } + * @param birthdate the birthdate to set + */ + @Override + public void setBirthdate(String birthdate) { + this.birthdate = birthdate; + } - /** + /** * Parse a JsonObject into a UserInfo. * @param o * @return @@ -379,7 +381,7 @@ public class DefaultUserInfo implements UserInfo { DefaultUserInfo ui = new DefaultUserInfo(); ui.setSub(obj.has("sub") ? obj.get("sub").getAsString() : null); - + ui.setName(obj.has("name") ? obj.get("name").getAsString() : null); ui.setPreferredUsername(obj.has("preferred_username") ? obj.get("preferred_username").getAsString() : null); ui.setGivenName(obj.has("given_name") ? obj.get("given_name").getAsString() : null); @@ -394,29 +396,29 @@ public class DefaultUserInfo implements UserInfo { ui.setLocale(obj.has("locale") ? obj.get("locale").getAsString() : null); ui.setUpdatedTime(obj.has("updated_time") ? obj.get("updated_time").getAsString() : null); ui.setBirthdate(obj.has("birthdate") ? obj.get("birthdate").getAsString() : null); - + ui.setEmail(obj.has("email") ? obj.get("email").getAsString() : null); ui.setEmailVerified(obj.has("email_verified") ? obj.get("email_verified").getAsBoolean() : null); - + ui.setPhoneNumber(obj.has("phone_number") ? obj.get("phone_number").getAsString() : null); - + if (obj.has("address") && obj.get("address").isJsonObject()) { JsonObject addr = obj.get("address").getAsJsonObject(); ui.setAddress(new Address()); - + ui.getAddress().setFormatted(addr.has("formatted") ? addr.get("formatted").getAsString() : null); ui.getAddress().setStreetAddress(addr.has("street_address") ? addr.get("street_address").getAsString() : null); ui.getAddress().setLocality(addr.has("locality") ? addr.get("locality").getAsString() : null); ui.getAddress().setRegion(addr.has("region") ? addr.get("region").getAsString() : null); ui.getAddress().setPostalCode(addr.has("postal_code") ? addr.get("postal_code").getAsString() : null); ui.getAddress().setCountry(addr.has("country") ? addr.get("country").getAsString() : null); - + } - + return ui; - + } } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Event.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Event.java index 1ef2551b6..1f9120591 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Event.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Event.java @@ -37,50 +37,50 @@ import javax.persistence.Temporal; public class Event { public static enum EventType { LOGIN, AUTHORIZATION, ACCESS } - + private Long id; private EventType type; private Date timestamp; /** - * @return the id - */ + * @return the id + */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) - public Long getId() { - return id; - } + public Long getId() { + return id; + } /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } /** - * @return the type - */ - public EventType getType() { - return type; - } + * @return the type + */ + public EventType getType() { + return type; + } /** - * @param type the type to set - */ - public void setType(EventType type) { - this.type = type; - } + * @param type the type to set + */ + public void setType(EventType type) { + this.type = type; + } /** - * @return the timestamp - */ - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - public Date getTimestamp() { - return timestamp; - } + * @return the timestamp + */ + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + public Date getTimestamp() { + return timestamp; + } /** - * @param timestamp the timestamp to set - */ - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } - + * @param timestamp the timestamp to set + */ + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Nonce.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Nonce.java index 0010ad539..7ecea00c2 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Nonce.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/Nonce.java @@ -23,16 +23,16 @@ import javax.persistence.Temporal; }) public class Nonce { - + private Long id; //the ID of this Nonce - + private String value; //the value of this Nonce - + private String clientId;//The id of the client who used this Nonce - + private Date useDate; //the date this Nonce was used - - private Date expireDate; //the date after which this Nonce should be removed from the database + + private Date expireDate; //the date after which this Nonce should be removed from the database /** * @return the id @@ -86,7 +86,7 @@ public class Nonce { * @return the useDate */ @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Temporal(javax.persistence.TemporalType.TIMESTAMP) @Column(name="use_date") public Date getUseDate() { return useDate; @@ -103,7 +103,7 @@ public class Nonce { * @return the expireDate */ @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Temporal(javax.persistence.TemporalType.TIMESTAMP) @Column(name="expire_date") public Date getExpireDate() { return expireDate; @@ -115,8 +115,8 @@ public class Nonce { public void setExpireDate(Date expireDate) { this.expireDate = expireDate; } - - - - + + + + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/UserInfo.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/UserInfo.java index adea96314..5829d7840 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/UserInfo.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/UserInfo.java @@ -12,12 +12,12 @@ public interface UserInfo { * @param sub the userId to set */ public abstract void setSub(String sub); - + /** * @return the preferred username */ public abstract String getPreferredUsername(); - + /** * @param preferredUsername the preferredUsername to set */ @@ -189,7 +189,7 @@ public interface UserInfo { * @return */ public abstract String getBirthdate(); - + /** * * @param birthdate diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/WhitelistedSite.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/WhitelistedSite.java index 10e84d9ce..4fb95deed 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/WhitelistedSite.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/WhitelistedSite.java @@ -32,7 +32,7 @@ import javax.persistence.NamedQuery; import javax.persistence.Table; /** - * Indicator that login to a site should be automatically granted + * Indicator that login to a site should be automatically granted * without user interaction. * @author jricher, aanganes * @@ -40,21 +40,21 @@ import javax.persistence.Table; @Entity @Table(name="whitelisted_site") @NamedQueries({ - @NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"), + @NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"), @NamedQuery(name = "WhitelistedSite.getByClientId", query = "select w from WhitelistedSite w where w.clientId = :clientId"), @NamedQuery(name = "WhitelistedSite.getByCreatoruserId", query = "select w from WhitelistedSite w where w.creatorUserId = :userId") }) public class WhitelistedSite { // unique id - private Long id; - - // Reference to the admin user who created this entry + private Long id; + + // Reference to the admin user who created this entry private String creatorUserId; - + // which OAuth2 client is this tied to private String clientId; - + // what scopes be allowed by default // this should include all information for what data to access private Set allowedScopes; @@ -63,14 +63,14 @@ public class WhitelistedSite { * Empty constructor */ public WhitelistedSite() { - + } - + /** * @return the id */ @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } @@ -103,9 +103,9 @@ public class WhitelistedSite { */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable( - name="whitelisted_site_scope", - joinColumns=@JoinColumn(name="owner_id") - ) + name="whitelisted_site_scope", + joinColumns=@JoinColumn(name="owner_id") + ) @Column(name="scope") public Set getAllowedScopes() { return allowedScopes; diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/ApprovedSiteRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/ApprovedSiteRepository.java index e78e55bb2..d896713ac 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/ApprovedSiteRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/ApprovedSiteRepository.java @@ -50,7 +50,7 @@ public interface ApprovedSiteRepository { * @param clientId * @param userId * @return - */ + */ public Collection getByClientIdAndUserId(String clientId, String userId); /** @@ -69,14 +69,14 @@ public interface ApprovedSiteRepository { * @return the persisted entity */ public ApprovedSite save(ApprovedSite approvedSite); - + /** * Get all sites approved by this user * @param userId * @return */ public Collection getByUserId(String userId); - + /** * Get all sites associated with this client * @param clientId diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/BlacklistedSiteRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/BlacklistedSiteRepository.java index e47073125..30051defc 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/BlacklistedSiteRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/BlacklistedSiteRepository.java @@ -14,13 +14,13 @@ import org.mitre.openid.connect.model.BlacklistedSite; public interface BlacklistedSiteRepository { public Collection getAll(); - + public BlacklistedSite getById(Long id); - + public void remove(BlacklistedSite blacklistedSite); - + public BlacklistedSite save(BlacklistedSite blacklistedSite); - + public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/EventRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/EventRepository.java index 542a400b3..60dc85bd0 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/EventRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/EventRepository.java @@ -47,8 +47,8 @@ public interface EventRepository { * @param startChunk * the start chuck of a list you desire * @param chunkSize - * the size of the chunk you desire - * + * the size of the chunk you desire + * * @return a Collection of Events */ public Collection getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize); diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/NonceRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/NonceRepository.java index 91c114485..396551c2d 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/NonceRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/NonceRepository.java @@ -1,6 +1,7 @@ package org.mitre.openid.connect.repository; import java.util.Collection; + import org.mitre.openid.connect.model.Nonce; /** @@ -19,14 +20,14 @@ public interface NonceRepository { * @return the nonce, if found */ public Nonce getById(Long id); - + /** * Remove the given Nonce from the database * * @param nonce the Nonce to remove */ public void remove(Nonce nonce); - + /** * Save a new Nonce in the database * @@ -34,21 +35,21 @@ public interface NonceRepository { * @return the saved Nonce */ public Nonce save(Nonce nonce); - + /** * Return all nonces stored in the database * * @return the set of nonces */ public Collection getAll(); - + /** * Return all expired nonces stored in the database * * @return the set of expired nonces */ public Collection getExpired(); - + /** * Return the set of nonces registered to the given client ID * @@ -56,5 +57,5 @@ public interface NonceRepository { * @return the set of nonces registered to the client */ public Collection getByClientId(String clientId); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java index 1027377e0..d2a8730a3 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java @@ -26,24 +26,24 @@ import org.mitre.openid.connect.model.UserInfo; * */ public interface UserInfoRepository { - + /** * Returns the UserInfo for the given subject * * @param sub * the subject of the UserInfo * @return a valid UserInfo if it exists, null otherwise - */ - public UserInfo getBySubject(String sub); - + */ + public UserInfo getBySubject(String sub); + /** - * Persists a UserInfo + * Persists a UserInfo * * @param user * @return */ public UserInfo save(UserInfo userInfo); - + /** * Removes the given UserInfo from the repository * @@ -64,6 +64,6 @@ public interface UserInfoRepository { * @param username * @return */ - public UserInfo getByUsername(String username); - + public UserInfo getByUsername(String username); + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/WhitelistedSiteRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/WhitelistedSiteRepository.java index 61d97e20c..866471af1 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/WhitelistedSiteRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/WhitelistedSiteRepository.java @@ -42,7 +42,7 @@ public interface WhitelistedSiteRepository { * @return a valid WhitelistedSite if it exists, null otherwise */ public WhitelistedSite getById(Long id); - + /** * Find a WhitelistedSite by its associated ClientDetails reference * @@ -50,7 +50,7 @@ public interface WhitelistedSiteRepository { * @return the corresponding WhitelistedSite if one exists for the RP, or null */ public WhitelistedSite getByClientId(String clientId); - + /** * Return a collection of the WhitelistedSites created by a given user * @@ -77,10 +77,10 @@ public interface WhitelistedSiteRepository { /** * Persist changes to a whitelistedSite. The ID of oldWhitelistedSite is retained. - * @param oldWhitelistedSite - * @param whitelistedSite - * @return - */ - public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite); + * @param oldWhitelistedSite + * @param whitelistedSite + * @return + */ + public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite); } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/ApprovedSiteService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/ApprovedSiteService.java index 36092bdb8..dc060259f 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/ApprovedSiteService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/ApprovedSiteService.java @@ -30,17 +30,17 @@ import org.springframework.security.oauth2.provider.ClientDetails; * */ public interface ApprovedSiteService { - - + + public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set allowedScopes, WhitelistedSite whitelistedSite); - + /** * Return a collection of all ApprovedSites * * @return the ApprovedSite collection, or null */ public Collection getAll(); - + /** * Return a collection of ApprovedSite managed by this repository matching the * provided client ID and user ID @@ -48,9 +48,9 @@ public interface ApprovedSiteService { * @param clientId * @param userId * @return - */ + */ public Collection getByClientIdAndUserId(String clientId, String userId); - + /** * Save an ApprovedSite * @@ -82,14 +82,14 @@ public interface ApprovedSiteService { * @return */ public Collection getByUserId(String userId); - + /** * Get all sites associated with this client * @param clientId * @return */ public Collection getByClientId(String clientId); - + /** * Clear out any approved sites for a given client. * @param client diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/BlacklistedSiteService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/BlacklistedSiteService.java index a33d7845e..695396c3c 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/BlacklistedSiteService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/BlacklistedSiteService.java @@ -14,15 +14,15 @@ import org.mitre.openid.connect.model.BlacklistedSite; public interface BlacklistedSiteService { public Collection getAll(); - + public BlacklistedSite getById(Long id); - + public void remove(BlacklistedSite blacklistedSite); - + public BlacklistedSite saveNew(BlacklistedSite blacklistedSite); - + public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite); public boolean isBlacklisted(String uri); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/NonceService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/NonceService.java index 093fd2063..59baebb5b 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/NonceService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/NonceService.java @@ -15,24 +15,24 @@ import org.mitre.openid.connect.model.Nonce; public interface NonceService { /** - * Create a new nonce. - * + * Create a new nonce. + * * @param clientId the ID of the client * @param value the value of the Nonce * @return the saved Nonce */ public Nonce create(String clientId, String value); - + /** * Check whether a given nonce value has been previously used and stored - * by the client. + * by the client. * * @param clientId the ID of the client * @param value the value of the nonce * @return true if the nonce has already been used, false otherwise */ - public boolean alreadyUsed(String clientId, String value); - + public boolean alreadyUsed(String clientId, String value); + /** * Return the nonce with the given ID * @@ -40,14 +40,14 @@ public interface NonceService { * @return the nonce, if found */ public Nonce getById(Long id); - + /** * Remove the given Nonce from the database * * @param nonce the Nonce to remove */ public void remove(Nonce nonce); - + /** * Save a new Nonce in the database * @@ -55,21 +55,21 @@ public interface NonceService { * @return the saved Nonce */ public Nonce save(Nonce nonce); - + /** * Return all nonces stored in the database * * @return the set of nonces */ public Collection getAll(); - + /** * Return all expired nonces stored in the database * * @return the set of expired nonces */ public Collection getExpired(); - + /** * Return the set of nonces registered to the given client ID * @@ -82,5 +82,5 @@ public interface NonceService { * Clear expired nonces from the database */ void clearExpiredNonces(); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/StatsService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/StatsService.java index bd6063258..c660993e3 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/StatsService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/StatsService.java @@ -14,9 +14,9 @@ public interface StatsService { /** * Calculate summary statistics * approvalCount: total approved sites - * userCount: unique users - * clientCount: unique clients - * + * userCount: unique users + * clientCount: unique clients + * * @return */ public Map calculateSummaryStats(); diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java index 0f1403127..ab21776b1 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java @@ -41,7 +41,7 @@ public interface UserInfoService { * @return UserInfo for sub, or null */ public UserInfo getBySubject(String userId); - + /** * Remove the UserInfo * diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/WhitelistedSiteService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/WhitelistedSiteService.java index dccfd439c..86eadc46b 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/WhitelistedSiteService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/WhitelistedSiteService.java @@ -33,7 +33,7 @@ public interface WhitelistedSiteService { * @return the WhitelistedSite collection, or null */ public Collection getAll(); - + /** * Returns the WhitelistedSite for the given id * @@ -50,7 +50,7 @@ public interface WhitelistedSiteService { * @return the corresponding WhitelistedSite if one exists for the RP, or null */ public WhitelistedSite getByClientId(String clientId); - + /** * Return a collection of the WhitelistedSites created by a given user * @@ -58,7 +58,7 @@ public interface WhitelistedSiteService { * @return the collection of corresponding WhitelistedSites, if any, or null */ public Collection getByCreator(String creatorId); - + /** * Removes the given WhitelistedSite from the repository * @@ -75,10 +75,10 @@ public interface WhitelistedSiteService { * @return */ public WhitelistedSite saveNew(WhitelistedSite whitelistedSite); - + /** * Updates an existing whitelisted site */ public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite); - + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/view/JwkKeyListView.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/view/JwkKeyListView.java index 1d90b7f46..06ede8c0c 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/view/JwkKeyListView.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/view/JwkKeyListView.java @@ -42,27 +42,27 @@ import com.nimbusds.jose.jwk.JWKSet; public class JwkKeyListView extends AbstractView { private static Logger logger = LoggerFactory.getLogger(JwkKeyListView.class); - + @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/json"); - - + + //BiMap keyMap = (BiMap) model.get("keys"); Map keys = (Map) model.get("keys"); - + JWKSet jwkSet = new JWKSet(new ArrayList(keys.values())); - + try { - + Writer out = response.getWriter(); out.write(jwkSet.toString()); - + } catch (IOException e) { - + logger.error("IOException in JwkKeyListView.java: ", e); - + } } diff --git a/openid-connect-common/src/main/java/org/mitre/util/jpa/JpaUtil.java b/openid-connect-common/src/main/java/org/mitre/util/jpa/JpaUtil.java index 6ecc5212c..76dd555ea 100644 --- a/openid-connect-common/src/main/java/org/mitre/util/jpa/JpaUtil.java +++ b/openid-connect-common/src/main/java/org/mitre/util/jpa/JpaUtil.java @@ -27,26 +27,26 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException; * Time: 2:13 PM */ public class JpaUtil { - public static T getSingleResult(List list) { - switch(list.size()) { - case 0: - return null; - case 1: - return list.get(0); - default: - throw new IncorrectResultSizeDataAccessException(1); - } - } + public static T getSingleResult(List list) { + switch(list.size()) { + case 0: + return null; + case 1: + return list.get(0); + default: + throw new IncorrectResultSizeDataAccessException(1); + } + } - public static T saveOrUpdate(I id, EntityManager entityManager, T entity) { - if (id == null) { - entityManager.persist(entity); - entityManager.flush(); - return entity; - } else { - T tmp = entityManager.merge(entity); - entityManager.flush(); - return tmp; - } - } + public static T saveOrUpdate(I id, EntityManager entityManager, T entity) { + if (id == null) { + entityManager.persist(entity); + entityManager.flush(); + return entity; + } else { + T tmp = entityManager.merge(entity); + entityManager.flush(); + return tmp; + } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/exception/DuplicateClientIdException.java b/openid-connect-server/src/main/java/org/mitre/oauth2/exception/DuplicateClientIdException.java index 0c0f424da..892ba161f 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/exception/DuplicateClientIdException.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/exception/DuplicateClientIdException.java @@ -18,13 +18,13 @@ package org.mitre.oauth2.exception; public class DuplicateClientIdException extends RuntimeException { public DuplicateClientIdException(String clientId) { - super("Duplicate client id: " + clientId); - } + super("Duplicate client id: " + clientId); + } /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 1L; + - } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java index dcd4e7654..de97477a1 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java @@ -17,7 +17,7 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe @PersistenceContext private EntityManager manager; - + @Override public AuthenticationHolderEntity getById(Long id) { return manager.find(AuthenticationHolderEntity.class, id); diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java index 1f696c91a..1accb383e 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java @@ -27,16 +27,16 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito @PersistenceContext EntityManager manager; - + /* (non-Javadoc) * @see org.mitre.oauth2.repository.AuthorizationCodeRepository#save(org.mitre.oauth2.model.AuthorizationCodeEntity) */ @Override @Transactional public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode) { - + return JpaUtil.saveOrUpdate(authorizationCode.getId(), manager, authorizationCode); - + } /* (non-Javadoc) @@ -45,20 +45,20 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito @Override @Transactional public OAuth2Authentication consume(String code) throws InvalidGrantException { - + TypedQuery query = manager.createNamedQuery("AuthorizationCodeEntity.getByValue", AuthorizationCodeEntity.class); query.setParameter("code", code); - + AuthorizationCodeEntity result = JpaUtil.getSingleResult(query.getResultList()); - + if (result == null) { throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code); } - + OAuth2Authentication authRequest = result.getAuthentication(); - + manager.remove(result); - + return authRequest; } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2ClientRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2ClientRepository.java index 113f6fca1..8dec1b5d9 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2ClientRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2ClientRepository.java @@ -37,15 +37,16 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository { @PersistenceContext private EntityManager manager; - + public JpaOAuth2ClientRepository() { - + } - + public JpaOAuth2ClientRepository(EntityManager manager) { this.manager = manager; } - + + @Override public ClientDetailsEntity getById(Long id) { return manager.find(ClientDetailsEntity.class, id); } @@ -82,17 +83,17 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository { } @Override - public ClientDetailsEntity updateClient(Long id, ClientDetailsEntity client) { + public ClientDetailsEntity updateClient(Long id, ClientDetailsEntity client) { // sanity check client.setId(id); - - return JpaUtil.saveOrUpdate(id, manager, client); - } + + return JpaUtil.saveOrUpdate(id, manager, client); + } @Override - public Collection getAllClients() { + public Collection getAllClients() { TypedQuery query = manager.createNamedQuery("ClientDetailsEntity.findAll", ClientDetailsEntity.class); return query.getResultList(); - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java index f6d89b37d..54f180981 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java @@ -42,18 +42,18 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository { query.setParameter("tokenValue", accessTokenValue); return JpaUtil.getSingleResult(query.getResultList()); } - + @Override public OAuth2AccessTokenEntity getAccessTokenById(Long id) { return manager.find(OAuth2AccessTokenEntity.class, id); } - + @Override @Transactional public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token) { return JpaUtil.saveOrUpdate(token.getId(), manager, token); } - + @Override @Transactional public void removeAccessToken(OAuth2AccessTokenEntity accessToken) { @@ -64,17 +64,17 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository { throw new IllegalArgumentException("Access token not found: " + accessToken); } } - + @Override @Transactional - public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) { + public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) { TypedQuery query = manager.createNamedQuery("OAuth2AccessTokenEntity.getByRefreshToken", OAuth2AccessTokenEntity.class); query.setParameter("refreshToken", refreshToken); - List accessTokens = query.getResultList(); - for (OAuth2AccessTokenEntity accessToken : accessTokens) { - removeAccessToken(accessToken); - } - } + List accessTokens = query.getResultList(); + for (OAuth2AccessTokenEntity accessToken : accessTokens) { + removeAccessToken(accessToken); + } + } @Override public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue) { @@ -82,105 +82,105 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository { query.setParameter("tokenValue", refreshTokenValue); return JpaUtil.getSingleResult(query.getResultList()); } - + @Override public OAuth2RefreshTokenEntity getRefreshTokenById(Long id) { return manager.find(OAuth2RefreshTokenEntity.class, id); } - + @Override @Transactional public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) { return JpaUtil.saveOrUpdate(refreshToken.getId(), manager, refreshToken); } - + @Override @Transactional - public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { + public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { OAuth2RefreshTokenEntity found = getRefreshTokenByValue(refreshToken.getValue()); if (found != null) { manager.remove(found); } else { throw new IllegalArgumentException("Refresh token not found: " + refreshToken); - } - } + } + } @Override @Transactional - public void clearTokensForClient(ClientDetailsEntity client) { + public void clearTokensForClient(ClientDetailsEntity client) { TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class); queryA.setParameter("client", client); - List accessTokens = queryA.getResultList(); - for (OAuth2AccessTokenEntity accessToken : accessTokens) { - removeAccessToken(accessToken); - } + List accessTokens = queryA.getResultList(); + for (OAuth2AccessTokenEntity accessToken : accessTokens) { + removeAccessToken(accessToken); + } TypedQuery queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class); queryR.setParameter("client", client); - List refreshTokens = queryR.getResultList(); - for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) { - removeRefreshToken(refreshToken); - } - } + List refreshTokens = queryR.getResultList(); + for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) { + removeRefreshToken(refreshToken); + } + } /* (non-Javadoc) - * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) - */ - @Override - public List getAccessTokensForClient(ClientDetailsEntity client) { + * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) + */ + @Override + public List getAccessTokensForClient(ClientDetailsEntity client) { TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class); queryA.setParameter("client", client); - List accessTokens = queryA.getResultList(); - return accessTokens; - } + List accessTokens = queryA.getResultList(); + return accessTokens; + } /* (non-Javadoc) - * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) - */ - @Override - public List getRefreshTokensForClient(ClientDetailsEntity client) { + * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) + */ + @Override + public List getRefreshTokensForClient(ClientDetailsEntity client) { TypedQuery queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class); queryR.setParameter("client", client); - List refreshTokens = queryR.getResultList(); - return refreshTokens; - } + List refreshTokens = queryR.getResultList(); + return refreshTokens; + } /* (non-Javadoc) - * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredAccessTokens() - */ - @Override - public List getExpiredAccessTokens() { + * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredAccessTokens() + */ + @Override + public List getExpiredAccessTokens() { TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getExpired", OAuth2AccessTokenEntity.class); - List accessTokens = queryA.getResultList(); - return accessTokens; - } + List accessTokens = queryA.getResultList(); + return accessTokens; + } /* (non-Javadoc) - * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredRefreshTokens() - */ - @Override - public List getExpiredRefreshTokens() { + * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredRefreshTokens() + */ + @Override + public List getExpiredRefreshTokens() { TypedQuery queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getExpired", OAuth2RefreshTokenEntity.class); - List refreshTokens = queryR.getResultList(); - return refreshTokens; - } - - @Override - public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) { - TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class); - queryA.setParameter("authentication", auth); - List accessTokens = queryA.getResultList(); - return JpaUtil.getSingleResult(accessTokens); - } + List refreshTokens = queryR.getResultList(); + return refreshTokens; + } + + @Override + public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) { + TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class); + queryA.setParameter("authentication", auth); + List accessTokens = queryA.getResultList(); + return JpaUtil.getSingleResult(accessTokens); + } /* (non-Javadoc) - * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) - */ - @Override - public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { - TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class); - queryA.setParameter("idToken", idToken); - List accessTokens = queryA.getResultList(); - return JpaUtil.getSingleResult(accessTokens); - } + * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) + */ + @Override + public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { + TypedQuery queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class); + queryA.setParameter("idToken", idToken); + List accessTokens = queryA.getResultList(); + return JpaUtil.getSingleResult(accessTokens); + } } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaSystemScopeRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaSystemScopeRepository.java index c11e81d03..b626bb557 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaSystemScopeRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaSystemScopeRepository.java @@ -3,6 +3,9 @@ */ package org.mitre.oauth2.repository.impl; +import static org.mitre.util.jpa.JpaUtil.getSingleResult; +import static org.mitre.util.jpa.JpaUtil.saveOrUpdate; + import java.util.LinkedHashSet; import java.util.Set; @@ -15,9 +18,6 @@ import org.mitre.oauth2.repository.SystemScopeRepository; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import static org.mitre.util.jpa.JpaUtil.getSingleResult; -import static org.mitre.util.jpa.JpaUtil.saveOrUpdate; - /** * @author jricher * @@ -27,7 +27,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository { @PersistenceContext private EntityManager em; - + /* (non-Javadoc) * @see org.mitre.oauth2.repository.SystemScopeRepository#getAll() */ @@ -35,7 +35,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository { @Transactional public Set getAll() { TypedQuery query = em.createNamedQuery("SystemScope.findAll", SystemScope.class); - + return new LinkedHashSet(query.getResultList()); } @@ -66,7 +66,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository { @Transactional public void remove(SystemScope scope) { SystemScope found = getById(scope.getId()); - + if (found != null) { em.remove(found); } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java index 8052e4e0a..57bef12e5 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java @@ -23,9 +23,9 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS @Autowired private AuthorizationCodeRepository repository; - + private RandomValueStringGenerator generator = new RandomValueStringGenerator(); - + /** * Generate a random authorization code and create an AuthorizationCodeEntity, * which will be stored in the repository. @@ -37,16 +37,16 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS @Override public String createAuthorizationCode(OAuth2Authentication authentication) { String code = generator.generate(); - + AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authentication); repository.save(entity); - + return code; } /** - * Consume a given authorization code. - * Match the provided string to an AuthorizationCodeEntity. If one is found, return + * Consume a given authorization code. + * Match the provided string to an AuthorizationCodeEntity. If one is found, return * the authentication associated with the code. If one is not found, throw an * InvalidGrantException. * @@ -56,7 +56,7 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS */ @Override public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException { - + OAuth2Authentication auth = repository.consume(code); return auth; } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java index 3dc2cd16a..a3680e20a 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java @@ -39,32 +39,32 @@ import com.google.common.base.Strings; @Service public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService { - + @Autowired private OAuth2ClientRepository clientRepository; - + @Autowired private OAuth2TokenRepository tokenRepository; - + @Autowired private ApprovedSiteService approvedSiteService; - + @Autowired private WhitelistedSiteService whitelistedSiteService; - + @Autowired private BlacklistedSiteService blacklistedSiteService; - + public DefaultOAuth2ClientDetailsEntityService() { - + } - - public DefaultOAuth2ClientDetailsEntityService(OAuth2ClientRepository clientRepository, + + public DefaultOAuth2ClientDetailsEntityService(OAuth2ClientRepository clientRepository, OAuth2TokenRepository tokenRepository) { this.clientRepository = clientRepository; this.tokenRepository = tokenRepository; } - + @Override public ClientDetailsEntity saveNewClient(ClientDetailsEntity client) { if (client.getId() != null) { // if it's not null, it's already been saved, this is an error @@ -76,37 +76,38 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt if (blacklistedSiteService.isBlacklisted(uri)) { throw new IllegalArgumentException("Client URI is blacklisted: " + uri); } - } + } } - - // assign a random clientid if it's empty + + // assign a random clientid if it's empty // NOTE: don't assign a random client secret without asking, since public clients have no secret - if (Strings.isNullOrEmpty(client.getClientId())) { - client = generateClientId(client); - } - - // if the client is flagged to allow for refresh tokens, make sure it's got the right granted scopes - if (client.isAllowRefresh()) { - client.getScope().add("offline_access"); - } else { - client.getScope().remove("offline_access"); - } - - // timestamp this to right now - client.setCreatedAt(new Date()); - - return clientRepository.saveClient(client); + if (Strings.isNullOrEmpty(client.getClientId())) { + client = generateClientId(client); + } + + // if the client is flagged to allow for refresh tokens, make sure it's got the right granted scopes + if (client.isAllowRefresh()) { + client.getScope().add("offline_access"); + } else { + client.getScope().remove("offline_access"); + } + + // timestamp this to right now + client.setCreatedAt(new Date()); + + return clientRepository.saveClient(client); } - + /** * Get the client by its internal ID */ + @Override public ClientDetailsEntity getClientById(Long id) { ClientDetailsEntity client = clientRepository.getById(id); - + return client; } - + /** * Get the client for the given ClientID */ @@ -121,87 +122,87 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt return client; } } - + throw new IllegalArgumentException("Client id must not be empty!"); } - + /** * Delete a client and all its associated tokens */ @Override - public void deleteClient(ClientDetailsEntity client) throws InvalidClientException { - + public void deleteClient(ClientDetailsEntity client) throws InvalidClientException { + if (clientRepository.getById(client.getId()) == null) { throw new InvalidClientException("Client with id " + client.getClientId() + " was not found"); } - + // clean out any tokens that this client had issued tokenRepository.clearTokensForClient(client); - + // clean out any approved sites for this client approvedSiteService.clearApprovedSitesForClient(client); - + // clear out any whitelisted sites for this client WhitelistedSite whitelistedSite = whitelistedSiteService.getByClientId(client.getClientId()); if (whitelistedSite != null) { - whitelistedSiteService.remove(whitelistedSite); + whitelistedSiteService.remove(whitelistedSite); } - + // take care of the client itself clientRepository.deleteClient(client); - + } /** - * Update the oldClient with information from the newClient. The + * Update the oldClient with information from the newClient. The * id from oldClient is retained. */ @Override - public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException { + public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException { if (oldClient != null && newClient != null) { - + for (String uri : newClient.getRegisteredRedirectUri()) { if (blacklistedSiteService.isBlacklisted(uri)) { throw new IllegalArgumentException("Client URI is blacklisted: " + uri); } - } - - // if the client is flagged to allow for refresh tokens, make sure it's got the right scope - if (newClient.isAllowRefresh()) { - newClient.getScope().add("offline_access"); - } else { - newClient.getScope().remove("offline_access"); - } + } - return clientRepository.updateClient(oldClient.getId(), newClient); + // if the client is flagged to allow for refresh tokens, make sure it's got the right scope + if (newClient.isAllowRefresh()) { + newClient.getScope().add("offline_access"); + } else { + newClient.getScope().remove("offline_access"); + } + + return clientRepository.updateClient(oldClient.getId(), newClient); } throw new IllegalArgumentException("Neither old client or new client can be null!"); - } + } /** * Get all clients in the system */ @Override - public Collection getAllClients() { + public Collection getAllClients() { return clientRepository.getAllClients(); - } + } /** * Generates a clientId for the given client and sets it to the client's clientId field. Returns the client that was passed in, now with id set. */ @Override - public ClientDetailsEntity generateClientId(ClientDetailsEntity client) { + public ClientDetailsEntity generateClientId(ClientDetailsEntity client) { client.setClientId(UUID.randomUUID().toString()); - return client; - } + return client; + } /** * Generates a new clientSecret for the given client and sets it to the client's clientSecret field. Returns the client that was passed in, now with secret set. */ @Override - public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) { + public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) { client.setClientSecret(Base64.encodeBase64URLSafeString(new BigInteger(512, new SecureRandom()).toByteArray()).replace("=", "")); - return client; - } + return client; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java index 2be02465d..7b0ba9826 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java @@ -59,159 +59,159 @@ import com.nimbusds.jwt.PlainJWT; */ @Service public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService { - + private static Logger logger = LoggerFactory.getLogger(DefaultOAuth2ProviderTokenService.class); @Autowired private OAuth2TokenRepository tokenRepository; - + @Autowired private AuthenticationHolderRepository authenticationHolderRepository; - + @Autowired private ClientDetailsEntityService clientDetailsService; - + @Autowired private TokenEnhancer tokenEnhancer; - + @Autowired private ApprovedSiteService approvedSiteService; - + @Override - public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException { + public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException { if (authentication != null && authentication.getOAuth2Request() != null) { // look up our client OAuth2Request clientAuth = authentication.getOAuth2Request(); - + ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); - + if (client == null) { throw new InvalidClientException("Client not found: " + clientAuth.getClientId()); } - + OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();//accessTokenFactory.createNewAccessToken(); - - // attach the client - token.setClient(client); - - // inherit the scope from the auth, but make a new set so it is - //not unmodifiable. Unmodifiables don't play nicely with Eclipselink, which - //wants to use the clone operation. - Set scopes = Sets.newHashSet(clientAuth.getScope()); - token.setScope(scopes); - // make it expire if necessary - if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) { - Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L)); - token.setExpiration(expiration); - } - - // attach the authorization so that we can look it up later - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setAuthentication(authentication); - authHolder = authenticationHolderRepository.save(authHolder); - - token.setAuthenticationHolder(authHolder); - - // attach a refresh token, if this client is allowed to request them and the user gets the offline scope - // TODO: tie this to some kind of scope service - if (client.isAllowRefresh() && scopes.contains("offline_access")) { - OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken(); - JWTClaimsSet refreshClaims = new JWTClaimsSet(); + // attach the client + token.setClient(client); - - // make it expire if necessary - if (client.getRefreshTokenValiditySeconds() != null) { - Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L)); - refreshToken.setExpiration(expiration); - refreshClaims.setExpirationTime(expiration); - } - - // set a random identifier - refreshClaims.setJWTID(UUID.randomUUID().toString()); + // inherit the scope from the auth, but make a new set so it is + //not unmodifiable. Unmodifiables don't play nicely with Eclipselink, which + //wants to use the clone operation. + Set scopes = Sets.newHashSet(clientAuth.getScope()); + token.setScope(scopes); + + // make it expire if necessary + if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) { + Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L)); + token.setExpiration(expiration); + } + + // attach the authorization so that we can look it up later + AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); + authHolder.setAuthentication(authentication); + authHolder = authenticationHolderRepository.save(authHolder); + + token.setAuthenticationHolder(authHolder); + + // attach a refresh token, if this client is allowed to request them and the user gets the offline scope + // TODO: tie this to some kind of scope service + if (client.isAllowRefresh() && scopes.contains("offline_access")) { + OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken(); + JWTClaimsSet refreshClaims = new JWTClaimsSet(); + + + // make it expire if necessary + if (client.getRefreshTokenValiditySeconds() != null) { + Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L)); + refreshToken.setExpiration(expiration); + refreshClaims.setExpirationTime(expiration); + } + + // set a random identifier + refreshClaims.setJWTID(UUID.randomUUID().toString()); + + // TODO: add issuer fields, signature to JWT + + PlainJWT refreshJwt = new PlainJWT(refreshClaims); + refreshToken.setJwt(refreshJwt); + + //Add the authentication + refreshToken.setAuthenticationHolder(authHolder); + refreshToken.setClient(client); + + + + // save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?) + tokenRepository.saveRefreshToken(refreshToken); + + token.setRefreshToken(refreshToken); + } + + tokenEnhancer.enhance(token, authentication); + + tokenRepository.saveAccessToken(token); + + //Add approved site reference, if any + OAuth2Request originalAuthRequest = authHolder.getAuthentication().getOAuth2Request(); + + if (originalAuthRequest.getExtensions() != null && originalAuthRequest.getExtensions().containsKey("approved_site")) { - // TODO: add issuer fields, signature to JWT - - PlainJWT refreshJwt = new PlainJWT(refreshClaims); - refreshToken.setJwt(refreshJwt); - - //Add the authentication - refreshToken.setAuthenticationHolder(authHolder); - refreshToken.setClient(client); - - - - // save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?) - tokenRepository.saveRefreshToken(refreshToken); - - token.setRefreshToken(refreshToken); - } - - tokenEnhancer.enhance(token, authentication); - - tokenRepository.saveAccessToken(token); - - //Add approved site reference, if any - OAuth2Request originalAuthRequest = authHolder.getAuthentication().getOAuth2Request(); - - if (originalAuthRequest.getExtensions() != null && originalAuthRequest.getExtensions().containsKey("approved_site")) { - Long apId = (Long) originalAuthRequest.getExtensions().get("approved_site"); ApprovedSite ap = approvedSiteService.getById(apId); Set apTokens = ap.getApprovedAccessTokens(); apTokens.add(token); ap.setApprovedAccessTokens(apTokens); approvedSiteService.save(ap); - + } - - if (token.getRefreshToken() != null) { - tokenRepository.saveRefreshToken(token.getRefreshToken()); // make sure we save any changes that might have been enhanced - } - - return token; + + if (token.getRefreshToken() != null) { + tokenRepository.saveRefreshToken(token.getRefreshToken()); // make sure we save any changes that might have been enhanced + } + + return token; } - - throw new AuthenticationCredentialsNotFoundException("No authentication credentials found"); - } + + throw new AuthenticationCredentialsNotFoundException("No authentication credentials found"); + } @Override - public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException { - + public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException { + OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue); - + if (refreshToken == null) { throw new InvalidTokenException("Invalid refresh token: " + refreshTokenValue); } - + ClientDetailsEntity client = refreshToken.getClient(); - + AuthenticationHolderEntity authHolder = refreshToken.getAuthenticationHolder(); - + //Make sure this client allows access token refreshing if (!client.isAllowRefresh()) { throw new InvalidClientException("Client does not allow refreshing access token!"); } - + // clear out any access tokens // TODO: make this a configurable option tokenRepository.clearAccessTokensForRefreshToken(refreshToken); - + if (refreshToken.isExpired()) { tokenRepository.removeRefreshToken(refreshToken); - throw new InvalidTokenException("Expired refresh token: " + refreshTokenValue); + throw new InvalidTokenException("Expired refresh token: " + refreshTokenValue); } - + // TODO: have the option to recycle the refresh token here, too // for now, we just reuse it as long as it's valid, which is the original intent - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); + OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); // get the stored scopes from the authentication holder's authorization request; these are the scopes associated with the refresh token Set refreshScopes = new HashSet(refreshToken.getAuthenticationHolder().getAuthentication().getOAuth2Request().getScope()); - + Set scope = new HashSet(authRequest.getScope()); - if (scope != null && !scope.isEmpty()) { + if (scope != null && !scope.isEmpty()) { // ensure a proper subset of scopes if (refreshScopes != null && refreshScopes.containsAll(scope)) { // set the scope of the new access token if requested @@ -225,189 +225,189 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi // otherwise inherit the scope of the refresh token (if it's there -- this can return a null scope set) token.setScope(refreshScopes); } - - token.setClient(client); - - if (client.getAccessTokenValiditySeconds() != null) { - Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L)); - token.setExpiration(expiration); - } - - token.setRefreshToken(refreshToken); - - token.setAuthenticationHolder(authHolder); - tokenEnhancer.enhance(token, authHolder.getAuthentication()); - - tokenRepository.saveAccessToken(token); - - return token; - - } + token.setClient(client); + + if (client.getAccessTokenValiditySeconds() != null) { + Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L)); + token.setExpiration(expiration); + } + + token.setRefreshToken(refreshToken); + + token.setAuthenticationHolder(authHolder); + + tokenEnhancer.enhance(token, authHolder.getAuthentication()); + + tokenRepository.saveAccessToken(token); + + return token; + + } @Override - public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException { - + public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException { + OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue); - + if (accessToken == null) { throw new InvalidTokenException("Invalid access token: " + accessTokenValue); } - + if (accessToken.isExpired()) { //tokenRepository.removeAccessToken(accessToken); revokeAccessToken(accessToken); throw new InvalidTokenException("Expired access token: " + accessTokenValue); } - - return accessToken.getAuthenticationHolder().getAuthentication(); - } + + return accessToken.getAuthenticationHolder().getAuthentication(); + } /** * Get an access token from its token value. */ @Override - public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue) throws AuthenticationException { + public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue) throws AuthenticationException { OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue); if (accessToken == null) { throw new InvalidTokenException("Access token for value " + accessTokenValue + " was not found"); } else { - return accessToken; + return accessToken; } - } + } /** * Get an access token by its authentication object. */ @Override public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication) { - + OAuth2AccessTokenEntity accessToken = tokenRepository.getByAuthentication(authentication); - + return accessToken; } - + /** * Get a refresh token by its token value. */ @Override - public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException { + public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException { OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue); if (refreshToken == null) { throw new InvalidTokenException("Refresh token for value " + refreshTokenValue + " was not found"); } else { - return refreshToken; + return refreshToken; } - } - + } + /** * Revoke a refresh token and all access tokens issued to it. */ @Override - public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { - tokenRepository.clearAccessTokensForRefreshToken(refreshToken); - tokenRepository.removeRefreshToken(refreshToken); - } + public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { + tokenRepository.clearAccessTokensForRefreshToken(refreshToken); + tokenRepository.removeRefreshToken(refreshToken); + } /** - * Revoke an access token. + * Revoke an access token. */ @Override - public void revokeAccessToken(OAuth2AccessTokenEntity accessToken) { - tokenRepository.removeAccessToken(accessToken); - } - + public void revokeAccessToken(OAuth2AccessTokenEntity accessToken) { + tokenRepository.removeAccessToken(accessToken); + } + /* (non-Javadoc) - * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) - */ - @Override - public List getAccessTokensForClient(ClientDetailsEntity client) { - return tokenRepository.getAccessTokensForClient(client); - } + * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) + */ + @Override + public List getAccessTokensForClient(ClientDetailsEntity client) { + return tokenRepository.getAccessTokensForClient(client); + } /* (non-Javadoc) - * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) - */ - @Override - public List getRefreshTokensForClient(ClientDetailsEntity client) { - return tokenRepository.getRefreshTokensForClient(client); - } + * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) + */ + @Override + public List getRefreshTokensForClient(ClientDetailsEntity client) { + return tokenRepository.getRefreshTokensForClient(client); + } - @Override - @Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes - public void clearExpiredTokens() { - logger.info("Cleaning out all expired tokens"); - - List accessTokens = tokenRepository.getExpiredAccessTokens(); - logger.info("Found " + accessTokens.size() + " expired access tokens"); - for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) { - revokeAccessToken(oAuth2AccessTokenEntity); - } - - List refreshTokens = tokenRepository.getExpiredRefreshTokens(); - logger.info("Found " + refreshTokens.size() + " expired refresh tokens"); - for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) { - revokeRefreshToken(oAuth2RefreshTokenEntity); - } - } - - /** + @Override + @Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes + public void clearExpiredTokens() { + logger.info("Cleaning out all expired tokens"); + + List accessTokens = tokenRepository.getExpiredAccessTokens(); + logger.info("Found " + accessTokens.size() + " expired access tokens"); + for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) { + revokeAccessToken(oAuth2AccessTokenEntity); + } + + List refreshTokens = tokenRepository.getExpiredRefreshTokens(); + logger.info("Found " + refreshTokens.size() + " expired refresh tokens"); + for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) { + revokeRefreshToken(oAuth2RefreshTokenEntity); + } + } + + /** * Get a builder object for this class (for tests) * @return */ public static DefaultOAuth2ProviderTokenServicesBuilder makeBuilder() { return new DefaultOAuth2ProviderTokenServicesBuilder(); } - + /** * Builder class for test harnesses. */ public static class DefaultOAuth2ProviderTokenServicesBuilder { private DefaultOAuth2ProviderTokenService instance; - + private DefaultOAuth2ProviderTokenServicesBuilder() { instance = new DefaultOAuth2ProviderTokenService(); } - + public DefaultOAuth2ProviderTokenServicesBuilder setTokenRepository(OAuth2TokenRepository tokenRepository) { instance.tokenRepository = tokenRepository; return this; } - + public DefaultOAuth2ProviderTokenServicesBuilder setClientDetailsService(ClientDetailsEntityService clientDetailsService) { instance.clientDetailsService = clientDetailsService; return this; } - + public DefaultOAuth2ProviderTokenServicesBuilder setTokenEnhancer(TokenEnhancer tokenEnhancer) { instance.tokenEnhancer = tokenEnhancer; return this; } - + public OAuth2TokenEntityService finish() { return instance; } } /* (non-Javadoc) - * @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) - */ - @Override - public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) { - return tokenRepository.saveAccessToken(accessToken); - } + * @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) + */ + @Override + public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) { + return tokenRepository.saveAccessToken(accessToken); + } /* (non-Javadoc) - * @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity) - */ - @Override - public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) { - return tokenRepository.saveRefreshToken(refreshToken); - } + * @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity) + */ + @Override + public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) { + return tokenRepository.saveRefreshToken(refreshToken); + } /** * @return the tokenEnhancer @@ -424,16 +424,16 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi } /* (non-Javadoc) - * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) - */ - @Override - public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { - return tokenRepository.getAccessTokenForIdToken(idToken); - } + * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) + */ + @Override + public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { + return tokenRepository.getAccessTokenForIdToken(idToken); + } @Override public OAuth2AccessTokenEntity getAccessTokenById(Long id) { return tokenRepository.getAccessTokenById(id); } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java index 8e368303b..684a8a0b8 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java @@ -29,132 +29,132 @@ public class DefaultSystemScopeService implements SystemScopeService { @Autowired private SystemScopeRepository repository; - + private Predicate isDefault = new Predicate() { @Override - public boolean apply(@Nullable SystemScope input) { + public boolean apply(@Nullable SystemScope input) { return (input != null && input.isDefaultScope()); - } + } }; - - + + private Predicate isDynReg = new Predicate() { @Override - public boolean apply(@Nullable SystemScope input) { + public boolean apply(@Nullable SystemScope input) { return (input != null && input.isAllowDynReg()); - } + } }; - + private Function stringToSystemScope = new Function() { @Override - public SystemScope apply(@Nullable String input) { + public SystemScope apply(@Nullable String input) { if (input == null) { return null; } else { - SystemScope s = getByValue(input); - if (s != null) { - // get the real scope if it's available - return s; - } else { - // make a fake one otherwise - return new SystemScope(input); - } + SystemScope s = getByValue(input); + if (s != null) { + // get the real scope if it's available + return s; + } else { + // make a fake one otherwise + return new SystemScope(input); + } } - } + } }; - + private Function systemScopeToString = new Function() { @Override - public String apply(@Nullable SystemScope input) { + public String apply(@Nullable SystemScope input) { if (input == null) { return null; } else { return input.getValue(); } - } + } }; - + /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#getAll() */ - @Override - public Set getAll() { - return repository.getAll(); - } + @Override + public Set getAll() { + return repository.getAll(); + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#getDefaults() */ - @Override - public Set getDefaults() { + @Override + public Set getDefaults() { return Sets.filter(getAll(), isDefault); - } + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#getDynReg() */ - @Override - public Set getDynReg() { - return Sets.filter(getAll(), isDynReg); - } + @Override + public Set getDynReg() { + return Sets.filter(getAll(), isDynReg); + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#getById(java.lang.Long) */ - @Override - public SystemScope getById(Long id) { - return repository.getById(id); - } + @Override + public SystemScope getById(Long id) { + return repository.getById(id); + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#getByValue(java.lang.String) */ - @Override - public SystemScope getByValue(String value) { - return repository.getByValue(value); - } + @Override + public SystemScope getByValue(String value) { + return repository.getByValue(value); + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#remove(org.mitre.oauth2.model.SystemScope) */ - @Override - public void remove(SystemScope scope) { - repository.remove(scope); - - } + @Override + public void remove(SystemScope scope) { + repository.remove(scope); + + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#save(org.mitre.oauth2.model.SystemScope) */ - @Override - public SystemScope save(SystemScope scope) { - return repository.save(scope); - } + @Override + public SystemScope save(SystemScope scope) { + return repository.save(scope); + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#fromStrings(java.util.Set) */ - @Override - public Set fromStrings(Set scope) { - if (scope == null) { - return null; - } else { - return new LinkedHashSet(Collections2.filter(Collections2.transform(scope, stringToSystemScope), Predicates.notNull())); - } - } + @Override + public Set fromStrings(Set scope) { + if (scope == null) { + return null; + } else { + return new LinkedHashSet(Collections2.filter(Collections2.transform(scope, stringToSystemScope), Predicates.notNull())); + } + } /* (non-Javadoc) * @see org.mitre.oauth2.service.SystemScopeService#toStrings(java.util.Set) */ - @Override - public Set toStrings(Set scope) { - if (scope == null) { - return null; - } else { - return new LinkedHashSet(Collections2.filter(Collections2.transform(scope, systemScopeToString), Predicates.notNull())); - } - } + @Override + public Set toStrings(Set scope) { + if (scope == null) { + return null; + } else { + return new LinkedHashSet(Collections2.filter(Collections2.transform(scope, systemScopeToString), Predicates.notNull())); + } + } + + - - } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java index 211383ad6..4e4779eaf 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java @@ -30,12 +30,12 @@ import com.google.common.collect.Sets; public class ChainedTokenGranter extends AbstractTokenGranter { private static final String grantType = "urn:ietf:params:oauth:grant_type:redelegate"; - + // keep down-cast versions so we can get to the right queries private OAuth2TokenEntityService tokenServices; - - - + + + /** * @param tokenServices * @param clientDetailsService @@ -46,52 +46,52 @@ public class ChainedTokenGranter extends AbstractTokenGranter { super(tokenServices, clientDetailsService, requestFactory, grantType); this.tokenServices = tokenServices; } - + /* (non-Javadoc) - * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) - */ - @Override - protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { - // read and load up the existing token - String incomingTokenValue = tokenRequest.getRequestParameters().get("token"); - OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); - - // check for scoping in the request, can't up-scope with a chained request - Set approvedScopes = incomingToken.getScope(); - Set requestedScopes = tokenRequest.getScope(); - - if (requestedScopes == null) { - requestedScopes = new HashSet(); - } - - // do a check on the requested scopes -- if they exactly match the client scopes, they were probably shadowed by the token granter - if (client.getScope().equals(requestedScopes)) { - requestedScopes = new HashSet(); - } - - // if our scopes are a valid subset of what's allowed, we can continue - if (approvedScopes.containsAll(requestedScopes)) { + * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) + */ + @Override + protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { + // read and load up the existing token + String incomingTokenValue = tokenRequest.getRequestParameters().get("token"); + OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); - if (requestedScopes.isEmpty()) { - // if there are no scopes, inherit the original scopes from the token - tokenRequest.setScope(approvedScopes); - } else { - // if scopes were asked for, give only the subset of scopes requested - // this allows safe downscoping - tokenRequest.setScope(Sets.intersection(requestedScopes, approvedScopes)); - } - - // NOTE: don't revoke the existing access token + // check for scoping in the request, can't up-scope with a chained request + Set approvedScopes = incomingToken.getScope(); + Set requestedScopes = tokenRequest.getScope(); + + if (requestedScopes == null) { + requestedScopes = new HashSet(); + } + + // do a check on the requested scopes -- if they exactly match the client scopes, they were probably shadowed by the token granter + if (client.getScope().equals(requestedScopes)) { + requestedScopes = new HashSet(); + } + + // if our scopes are a valid subset of what's allowed, we can continue + if (approvedScopes.containsAll(requestedScopes)) { + + if (requestedScopes.isEmpty()) { + // if there are no scopes, inherit the original scopes from the token + tokenRequest.setScope(approvedScopes); + } else { + // if scopes were asked for, give only the subset of scopes requested + // this allows safe downscoping + tokenRequest.setScope(Sets.intersection(requestedScopes, approvedScopes)); + } + + // NOTE: don't revoke the existing access token + + // create a new access token + OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createOAuth2Request(client, tokenRequest), incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication()); + + return authentication; + + } else { + throw new InvalidScopeException("Invalid scope requested in chained request", approvedScopes); + } + + } - // create a new access token - OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createOAuth2Request(client, tokenRequest), incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication()); - - return authentication; - - } else { - throw new InvalidScopeException("Invalid scope requested in chained request", approvedScopes); - } - - } - } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java index 682fc5b23..1bd5d4164 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java @@ -40,124 +40,124 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter { // keep down-cast versions so we can get to the right queries private OAuth2TokenEntityService tokenServices; - + @Autowired private JwtSigningAndValidationService jwtService; - + @Autowired private ConfigurationPropertiesBean config; - + @Autowired public JwtAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, grantType); - this.tokenServices = tokenServices; - } + super(tokenServices, clientDetailsService, requestFactory, grantType); + this.tokenServices = tokenServices; + } /* (non-Javadoc) - * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) - */ - @Override - protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { - // read and load up the existing token - String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion"); - OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); - - if (incomingToken.getScope().contains(OAuth2AccessTokenEntity.ID_TOKEN_SCOPE)) { - - if (!client.getClientId().equals(tokenRequest.getClientId())) { - throw new InvalidClientException("Not the right client for this token"); - } + * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) + */ + @Override + protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { + // read and load up the existing token + String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion"); + OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); - // it's an ID token, process it accordingly - - try { - - // TODO: make this use a more specific idtoken class - JWT idToken = JWTParser.parse(incomingTokenValue); - - OAuth2AccessTokenEntity accessToken = tokenServices.getAccessTokenForIdToken(incomingToken); - - if (accessToken != null) { - - //OAuth2AccessTokenEntity newIdToken = tokenServices.get - - OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity(); - - // copy over all existing claims - JWTClaimsSet claims = new JWTClaimsSet(idToken.getJWTClaimsSet()); - - if (client instanceof ClientDetailsEntity) { - - ClientDetailsEntity clientEntity = (ClientDetailsEntity) client; - - // update expiration and issued-at claims + if (incomingToken.getScope().contains(OAuth2AccessTokenEntity.ID_TOKEN_SCOPE)) { + + if (!client.getClientId().equals(tokenRequest.getClientId())) { + throw new InvalidClientException("Not the right client for this token"); + } + + // it's an ID token, process it accordingly + + try { + + // TODO: make this use a more specific idtoken class + JWT idToken = JWTParser.parse(incomingTokenValue); + + OAuth2AccessTokenEntity accessToken = tokenServices.getAccessTokenForIdToken(incomingToken); + + if (accessToken != null) { + + //OAuth2AccessTokenEntity newIdToken = tokenServices.get + + OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity(); + + // copy over all existing claims + JWTClaimsSet claims = new JWTClaimsSet(idToken.getJWTClaimsSet()); + + if (client instanceof ClientDetailsEntity) { + + ClientDetailsEntity clientEntity = (ClientDetailsEntity) client; + + // update expiration and issued-at claims if (clientEntity.getIdTokenValiditySeconds() != null) { Date expiration = new Date(System.currentTimeMillis() + (clientEntity.getIdTokenValiditySeconds() * 1000L)); claims.setExpirationTime(expiration); newIdTokenEntity.setExpiration(expiration); } - - } else { - //TODO: What should happen in this case? Is this possible? - } - + + } else { + //TODO: What should happen in this case? Is this possible? + } + claims.setIssueTime(new Date()); - - + + SignedJWT newIdToken = new SignedJWT((JWSHeader) idToken.getHeader(), claims); - jwtService.signJwt(newIdToken); - + jwtService.signJwt(newIdToken); + newIdTokenEntity.setJwt(newIdToken); newIdTokenEntity.setAuthenticationHolder(incomingToken.getAuthenticationHolder()); newIdTokenEntity.setScope(incomingToken.getScope()); newIdTokenEntity.setClient(incomingToken.getClient()); - + newIdTokenEntity = tokenServices.saveAccessToken(newIdTokenEntity); - + // attach the ID token to the access token entity accessToken.setIdToken(newIdTokenEntity); accessToken = tokenServices.saveAccessToken(accessToken); - + // delete the old ID token tokenServices.revokeAccessToken(incomingToken); - - return newIdTokenEntity; - - } - } catch (ParseException e) { - logger.warn("Couldn't parse id token", e); - } - - } - - // if we got down here, we didn't actually create any tokens, so return null - - return null; - /* - * Otherwise, process it like an access token assertion ... which we don't support yet so this is all commented out - * / + return newIdTokenEntity; + + } + } catch (ParseException e) { + logger.warn("Couldn't parse id token", e); + } + + } + + // if we got down here, we didn't actually create any tokens, so return null + + return null; + + /* + * Otherwise, process it like an access token assertion ... which we don't support yet so this is all commented out + * / if (jwtService.validateSignature(incomingTokenValue)) { Jwt jwt = Jwt.parse(incomingTokenValue); - - + + if (oldToken.getScope().contains("id-token")) { // TODO: things } - + // TODO: should any of these throw an exception instead of returning null? JwtClaims claims = jwt.getClaims(); if (!config.getIssuer().equals(claims.getIssuer())) { // issuer isn't us return null; } - + if (!authorizationRequest.getClientId().equals(claims.getAudience())) { // audience isn't the client return null; } - + Date now = new Date(); if (!now.after(claims.getExpiration())) { // token is expired @@ -171,14 +171,14 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter { // we might need new calls on the token services layer to handle this, and we might // need to handle id tokens separately. return new OAuth2Authentication(authorizationRequest, null); - + } else { return null; // throw error?? } - */ - - } + */ + + } + + - - } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java b/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java index 978494e92..e71f18a0f 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java @@ -43,11 +43,11 @@ import com.google.gson.JsonSerializer; @Component("tokenIntrospection") public class TokenIntrospectionView extends AbstractView { - + private static Logger logger = LoggerFactory.getLogger(TokenIntrospectionView.class); @Override - protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() { @@ -68,7 +68,7 @@ public class TokenIntrospectionView extends AbstractView { // serialize other classes without filter (lists and sets and things) return false; } - */ + */ return false; } @@ -84,28 +84,29 @@ public class TokenIntrospectionView extends AbstractView { }) .registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer() { - public JsonElement serialize(OAuth2AccessTokenEntity src, Type typeOfSrc, JsonSerializationContext context) { - JsonObject token = new JsonObject(); - - token.addProperty("valid", true); - - JsonArray scopes = new JsonArray(); - for (String scope : src.getScope()) { - scopes.add(new JsonPrimitive(scope)); - } - token.add("scope", scopes); - - token.add("expires_at", context.serialize(src.getExpiration())); - - //token.addProperty("audience", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId()); - - token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName()); - - token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getClientId()); - - return token; - } - + @Override + public JsonElement serialize(OAuth2AccessTokenEntity src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject token = new JsonObject(); + + token.addProperty("valid", true); + + JsonArray scopes = new JsonArray(); + for (String scope : src.getScope()) { + scopes.add(new JsonPrimitive(scope)); + } + token.add("scope", scopes); + + token.add("expires_at", context.serialize(src.getExpiration())); + + //token.addProperty("audience", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId()); + + token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName()); + + token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getClientId()); + + return token; + } + }) .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") .create(); @@ -113,9 +114,9 @@ public class TokenIntrospectionView extends AbstractView { response.setContentType("application/json"); Writer out; - + try { - + out = response.getWriter(); Object obj = model.get("entity"); if (obj == null) { @@ -123,13 +124,13 @@ public class TokenIntrospectionView extends AbstractView { } gson.toJson(obj, out); - + } catch (IOException e) { - + logger.error("IOException occurred in TokenIntrospectionView.java: ", e); - + } - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java index cee14e312..df958180b 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java @@ -44,48 +44,48 @@ public class IntrospectionEndpoint { @Autowired private OAuth2TokenEntityService tokenServices; - + @Autowired private ClientDetailsEntityService clientService; - + private static Logger logger = LoggerFactory.getLogger(IntrospectionEndpoint.class); - + public IntrospectionEndpoint() { - + } - + public IntrospectionEndpoint(OAuth2TokenEntityService tokenServices) { this.tokenServices = tokenServices; } - + @ExceptionHandler(InvalidTokenException.class) public ModelAndView tokenNotFound(InvalidTokenException ex) { Map e = ImmutableMap.of("valid", Boolean.FALSE); Map model = new HashMap(); model.put("entity", e); - + logger.error("InvalidTokenException: ", ex); - + model.put("code", HttpStatus.BAD_REQUEST); - + return new ModelAndView("jsonEntityView", model); } - + @PreAuthorize("hasRole('ROLE_CLIENT')") @RequestMapping("/introspect") public ModelAndView verify(@RequestParam("token") String tokenValue, Principal p, ModelAndView modelAndView) { - + /* if (p != null && p instanceof OAuth2Authentication) { OAuth2Authentication auth = (OAuth2Authentication)p; - + if (auth.getDetails() != null && auth.getDetails() instanceof OAuth2AuthenticationDetails) { OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)auth.getDetails(); - + String tokenValue = details.getTokenValue(); - + OAuth2AccessTokenEntity token = tokenServices.readAccessToken(tokenValue); - + if (token != null) { // if it's a valid token, we'll print out the scope and expiration modelAndView.setViewName("tokenIntrospection"); @@ -93,36 +93,36 @@ public class IntrospectionEndpoint { } } }*/ - + if (Strings.isNullOrEmpty(tokenValue)) { logger.error("Verify failed; token value is null"); modelAndView.addObject("code", HttpStatus.BAD_REQUEST); modelAndView.setViewName("httpCodeView"); return modelAndView; } - + OAuth2AccessTokenEntity token = null; - + try { - token = tokenServices.readAccessToken(tokenValue); + token = tokenServices.readAccessToken(tokenValue); } catch (AuthenticationException e) { logger.error("Verify failed; AuthenticationException: ", e); modelAndView.addObject("code", HttpStatus.FORBIDDEN); modelAndView.setViewName("httpCodeView"); return modelAndView; } - + ClientDetailsEntity tokenClient = token.getClient(); // clientID is the principal name in the authentication String clientId = p.getName(); ClientDetailsEntity authClient = clientService.loadClientByClientId(clientId); - + if (tokenClient != null && authClient != null) { if (authClient.isAllowIntrospection()) { - + // if it's the same client that the token was issued to, or it at least has all the scopes the token was issued with if (authClient.equals(tokenClient) || authClient.getScope().containsAll(token.getScope())) { - + // if it's a valid token, we'll print out information on it modelAndView.setViewName("tokenIntrospection"); modelAndView.addObject("entity", token); @@ -146,7 +146,7 @@ public class IntrospectionEndpoint { modelAndView.setViewName("httpCodeView"); return modelAndView; } - + } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java index eae313455..b244198d5 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java @@ -51,20 +51,20 @@ public class OAuthConfirmationController { @Autowired private ClientDetailsEntityService clientService; - + @Autowired private SystemScopeService scopeService; - + private static Logger logger = LoggerFactory.getLogger(OAuthConfirmationController.class); - + public OAuthConfirmationController() { - + } - + public OAuthConfirmationController(ClientDetailsEntityService clientService) { this.clientService = clientService; } - + @PreAuthorize("hasRole('ROLE_USER')") @RequestMapping("/oauth/confirm_access") public ModelAndView confimAccess(Map model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) { @@ -72,10 +72,10 @@ public class OAuthConfirmationController { //AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest"); ClientDetails client = null; - + try { client = clientService.loadClientByClientId(clientAuth.getClientId()); - } catch (OAuth2Exception e) { + } catch (OAuth2Exception e) { logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client: " , e); model.put("code", HttpStatus.BAD_REQUEST); @@ -86,7 +86,7 @@ public class OAuthConfirmationController { model.put("code", HttpStatus.BAD_REQUEST); return new ModelAndView("httpCodeView"); } - + if (client == null) { logger.error("confirmAccess: could not find client " + clientAuth.getClientId()); model.put("code", HttpStatus.NOT_FOUND); @@ -96,49 +96,49 @@ public class OAuthConfirmationController { model.put("client", client); String redirect_uri = clientAuth.getRequestParameters().get("redirect_uri"); - - model.put("redirect_uri", redirect_uri); - - /* + model.put("redirect_uri", redirect_uri); + + + /* Map scopes = new HashMap(); for (String scope : clientAuth.getScope()) { scopes.put(scope, Boolean.TRUE); } - */ - - Set scopes = scopeService.fromStrings(clientAuth.getScope()); - - Set sortedScopes = new LinkedHashSet(scopes.size()); - Set systemScopes = scopeService.getAll(); - - // sort scopes for display - for (SystemScope s : systemScopes) { - if (scopes.contains(s)) { - sortedScopes.add(s); - } - } - - sortedScopes.addAll(Sets.difference(scopes, systemScopes)); - - model.put("scopes", sortedScopes); - - return new ModelAndView("oauth/approve", model); + */ + + Set scopes = scopeService.fromStrings(clientAuth.getScope()); + + Set sortedScopes = new LinkedHashSet(scopes.size()); + Set systemScopes = scopeService.getAll(); + + // sort scopes for display + for (SystemScope s : systemScopes) { + if (scopes.contains(s)) { + sortedScopes.add(s); + } + } + + sortedScopes.addAll(Sets.difference(scopes, systemScopes)); + + model.put("scopes", sortedScopes); + + return new ModelAndView("oauth/approve", model); } /** - * @return the clientService - */ - public ClientDetailsEntityService getClientService() { - return clientService; - } + * @return the clientService + */ + public ClientDetailsEntityService getClientService() { + return clientService; + } /** - * @param clientService the clientService to set - */ - public void setClientService(ClientDetailsEntityService clientService) { - this.clientService = clientService; - } - - + * @param clientService the clientService to set + */ + public void setClientService(ClientDetailsEntityService clientService) { + this.clientService = clientService; + } + + } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java index 62790a234..4969158dc 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java @@ -38,52 +38,52 @@ import org.springframework.web.servlet.ModelAndView; public class RevocationEndpoint { @Autowired OAuth2TokenEntityService tokenServices; - + private static Logger logger = LoggerFactory.getLogger(RevocationEndpoint.class); - + public RevocationEndpoint() { - + } - + public RevocationEndpoint(OAuth2TokenEntityService tokenServices) { this.tokenServices = tokenServices; } - + // TODO @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") @RequestMapping("/revoke") public ModelAndView revoke(@RequestParam("token") String tokenValue, Principal principal, ModelAndView modelAndView) { - + OAuth2RefreshTokenEntity refreshToken = null; OAuth2AccessTokenEntity accessToken = null; try { - refreshToken = tokenServices.getRefreshToken(tokenValue); - } catch (InvalidTokenException e) { - // it's OK if either of these tokens are bad - //TODO: Error Handling - } + refreshToken = tokenServices.getRefreshToken(tokenValue); + } catch (InvalidTokenException e) { + // it's OK if either of these tokens are bad + //TODO: Error Handling + } try { - accessToken = tokenServices.readAccessToken(tokenValue); - } catch (InvalidTokenException e) { - // it's OK if either of these tokens are bad - //TODO: Error Handling - } catch (AuthenticationException e) { - //TODO: Error Handling - } - + accessToken = tokenServices.readAccessToken(tokenValue); + } catch (InvalidTokenException e) { + // it's OK if either of these tokens are bad + //TODO: Error Handling + } catch (AuthenticationException e) { + //TODO: Error Handling + } + if (refreshToken == null && accessToken == null) { //TODO: Error Handling // TODO: this should throw a 400 with a JSON error code throw new InvalidTokenException("Invalid OAuth token: " + tokenValue); } - + if (principal instanceof OAuth2Authentication) { //TODO what is this variable for? It is unused. is it just a validation check? OAuth2AccessTokenEntity tok = tokenServices.getAccessToken((OAuth2Authentication) principal); - + // we've got a client acting on its own behalf, not an admin //ClientAuthentication clientAuth = (ClientAuthenticationToken) ((OAuth2Authentication) auth).getClientAuthentication(); OAuth2Request clientAuth = ((OAuth2Authentication) principal).getOAuth2Request(); @@ -91,27 +91,27 @@ public class RevocationEndpoint { if (refreshToken != null) { if (!refreshToken.getClient().getClientId().equals(clientAuth.getClientId())) { // trying to revoke a token we don't own, fail - // TODO: this should throw a 403 + // TODO: this should throw a 403 //TODO: Error Handling throw new PermissionDeniedException("Client tried to revoke a token it doesn't own"); } } else { if (!accessToken.getClient().getClientId().equals(clientAuth.getClientId())) { // trying to revoke a token we don't own, fail - // TODO: this should throw a 403 + // TODO: this should throw a 403 //TODO: Error Handling throw new PermissionDeniedException("Client tried to revoke a token it doesn't own"); } } } - + // if we got this far, we're allowed to do this if (refreshToken != null) { tokenServices.revokeRefreshToken(refreshToken); } else { tokenServices.revokeAccessToken(accessToken); } - + // TODO: throw a 200 back (no content?) return modelAndView; } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/ScopeAPI.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/ScopeAPI.java index f00d46853..58830f5e2 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/ScopeAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/ScopeAPI.java @@ -5,9 +5,6 @@ package org.mitre.oauth2.web; import java.util.Set; -import javax.persistence.EntityExistsException; -import javax.persistence.TransactionRequiredException; - import org.mitre.oauth2.model.SystemScope; import org.mitre.oauth2.service.SystemScopeService; import org.slf4j.Logger; @@ -35,35 +32,35 @@ public class ScopeAPI { @Autowired private SystemScopeService scopeService; - + private static Logger logger = LoggerFactory.getLogger(ScopeAPI.class); - + private Gson gson = new Gson(); - + @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") public String getAll(ModelMap m) { - + Set allScopes = scopeService.getAll(); - + m.put("entity", allScopes); - + return "jsonEntityView"; } - + @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json") public String getScope(@PathVariable("id") Long id, ModelMap m) { - + SystemScope scope = scopeService.getById(id); - + if (scope != null) { - + m.put("entity", scope); - + return "jsonEntityView"; } else { - + logger.error("getScope failed; scope not found: " + id); - + m.put("code", HttpStatus.NOT_FOUND); m.put("errorMessage", "The requested scope with id " + id + " could not be found."); return "jsonErrorView"; @@ -73,46 +70,46 @@ public class ScopeAPI { @PreAuthorize("hasRole('ROLE_ADMIN')") @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json") public String updateScope(@PathVariable("id") Long id, @RequestBody String json, ModelMap m) { - + SystemScope existing = scopeService.getById(id); - + SystemScope scope = gson.fromJson(json, SystemScope.class); - + if (existing != null && scope != null) { - + if (existing.getId().equals(scope.getId())) { // sanity check - + scope = scopeService.save(scope); - + m.put("entity", scope); - + return "jsonEntityView"; } else { - - logger.error("updateScope failed; scope ids to not match: got " + + logger.error("updateScope failed; scope ids to not match: got " + existing.getId() + " and " + scope.getId()); - + m.put("code", HttpStatus.BAD_REQUEST); - m.put("errorMessage", "Could not update scope. Scope ids to not match: got " + m.put("errorMessage", "Could not update scope. Scope ids to not match: got " + existing.getId() + " and " + scope.getId()); return "jsonErrorView"; } - + } else { - + logger.error("updateScope failed; scope with id " + id + " not found."); m.put("code", HttpStatus.NOT_FOUND); m.put("errorMessage", "Could not update scope. The scope with id " + id + " could not be found."); return "jsonErrorView"; } } - + @PreAuthorize("hasRole('ROLE_ADMIN')") @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json", consumes = "application/json") public String createScope(@RequestBody String json, ModelMap m) { SystemScope scope = gson.fromJson(json, SystemScope.class); - + SystemScope alreadyExists = scopeService.getByValue(scope.getValue()); if (alreadyExists != null) { //Error, cannot save a scope with the same value as an existing one @@ -121,41 +118,41 @@ public class ScopeAPI { m.put("errorMessage", "A scope with value " + scope.getValue() + " already exists, please choose a different value."); return "jsonErrorView"; } - + scope = scopeService.save(scope); if (scope != null && scope.getId() != null) { m.put("entity", scope); - + return "jsonEntityView"; } else { - + logger.error("createScope failed; JSON was invalid: " + json); m.put("code", HttpStatus.BAD_REQUEST); m.put("errorMessage", "Could not save new scope " + scope.getValue() + ". The scope service failed to return a saved entity."); return "jsonErrorView"; - + } } - + @PreAuthorize("hasRole('ROLE_ADMIN')") @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) public String deleteScope(@PathVariable("id") Long id, ModelMap m) { SystemScope existing = scopeService.getById(id); - + if (existing != null) { scopeService.remove(existing); - + return "httpCodeView"; } else { - + logger.error("deleteScope failed; scope with id " + id + " not found."); m.put("code", HttpStatus.NOT_FOUND); m.put("errorMessage", "Could not delete scope. The requested scope with id " + id + " could not be found."); return "jsonErrorView"; } } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java index 94a7a4f61..6e928a081 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java @@ -36,10 +36,10 @@ import com.nimbusds.jwt.SignedJWT; public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { private static Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestFactory.class); - + //@Autowired private NonceService nonceService; - + //@Autowired private ClientDetailsEntityService clientDetailsService; @@ -58,7 +58,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { this.clientDetailsService = clientDetailsService; this.nonceService = nonceService; } - + /** * Default empty constructor */ @@ -70,28 +70,28 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { public AuthorizationRequest createAuthorizationRequest(Map inputParams) { Map parameters = processRequestObject(inputParams); - + String clientId = parameters.get("client_id"); ClientDetails client = null; - + if (clientId != null) { client = clientDetailsService.loadClientByClientId(clientId); } - + String requestNonce = parameters.get("nonce"); - - AuthorizationRequest request = new AuthorizationRequest(parameters, Collections. emptyMap(), - parameters.get(OAuth2Utils.CLIENT_ID), + + AuthorizationRequest request = new AuthorizationRequest(parameters, Collections. emptyMap(), + parameters.get(OAuth2Utils.CLIENT_ID), OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null, - null, false, parameters.get(OAuth2Utils.STATE), - parameters.get(OAuth2Utils.REDIRECT_URI), + null, false, parameters.get(OAuth2Utils.STATE), + parameters.get(OAuth2Utils.REDIRECT_URI), OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.RESPONSE_TYPE))); - - //Only process if the user is authenticated. If the user is not authenticated yet, this - //code will be called a second time once the user is redirected from the login page back + + //Only process if the user is authenticated. If the user is not authenticated yet, this + //code will be called a second time once the user is redirected from the login page back //to the auth endpoint. Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - + if (requestNonce != null && principal != null && principal instanceof User) { if (!nonceService.alreadyUsed(clientId, requestNonce)) { @@ -101,18 +101,18 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { else { throw new NonceReuseException(client == null ? "unidentified client" : client.getClientId(), requestNonce); } - + } - + Set scopes = OAuth2Utils.parseParameterList(parameters.get("scope")); if ((scopes == null || scopes.isEmpty()) && client != null) { //TODO: do we want to allow default scoping at all? Set clientScopes = client.getScope(); scopes = clientScopes; } - + request.setScope(scopes); - + return request; } @@ -120,46 +120,46 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { * @param inputParams * @return */ - private Map processRequestObject(Map inputParams) { - - String jwtString = inputParams.get("request"); - - // if there's no request object, bail early - if (Strings.isNullOrEmpty(jwtString)) { - return inputParams; - } + private Map processRequestObject(Map inputParams) { - // start by copying over what's already in there - Map parameters = new HashMap(inputParams); + String jwtString = inputParams.get("request"); + + // if there's no request object, bail early + if (Strings.isNullOrEmpty(jwtString)) { + return inputParams; + } + + // start by copying over what's already in there + Map parameters = new HashMap(inputParams); + + // parse the request object + try { + SignedJWT jwsObject = SignedJWT.parse(jwtString); + JSONObject claims = jwsObject.getPayload().toJSONObject(); - // parse the request object - try { - SignedJWT jwsObject = SignedJWT.parse(jwtString); - JSONObject claims = jwsObject.getPayload().toJSONObject(); - // TODO: check parameter consistency, move keys to constants - + String clientId = JSONObjectUtils.getString(claims, "client_id"); if (clientId != null) { parameters.put("client_id", clientId); } - + ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientId); if (client.getJwksUri() == null) { throw new InvalidClientException("Client must have a JWK URI registered to use request objects."); } - + // check JWT signature JwtSigningAndValidationService validator = validators.get(client.getJwksUri()); if (validator == null) { throw new InvalidClientException("Client must have a JWK URI registered to use request objects."); } - + if (!validator.validateSignature(jwsObject)) { throw new AuthenticationServiceException("Signature did not validate for presented JWT request object."); } - + /* * if (in Claims): * if (in params): @@ -172,57 +172,57 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { * else (not in claims): * we don't care */ - + String responseTypes = JSONObjectUtils.getString(claims, "response_type"); if (responseTypes != null) { parameters.put("response_type", responseTypes); } - + if (claims.get("redirect_uri") != null) { if (inputParams.containsKey("redirect_uri") == false) { parameters.put("redirect_uri", JSONObjectUtils.getString(claims, "redirect_uri")); } } - + String state = JSONObjectUtils.getString(claims, "state"); if(state != null) { if (inputParams.containsKey("state") == false) { parameters.put("state", state); } } - + String nonce = JSONObjectUtils.getString(claims, "nonce"); if(nonce != null) { if (inputParams.containsKey("nonce") == false) { parameters.put("nonce", nonce); } } - + String display = JSONObjectUtils.getString(claims, "display"); if (display != null) { if (inputParams.containsKey("display") == false) { parameters.put("display", display); } } - + String prompt = JSONObjectUtils.getString(claims, "prompt"); if (prompt != null) { if (inputParams.containsKey("prompt") == false) { parameters.put("prompt", prompt); } } - + String scope = JSONObjectUtils.getString(claims, "scope"); if (scope != null) { if (inputParams.containsKey("scope") == false) { parameters.put("scope", scope); } } - - } catch (ParseException e) { - logger.error("ParseException while parsing RequestObject:", e); - } + + } catch (ParseException e) { + logger.error("ParseException while parsing RequestObject:", e); + } return parameters; - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAssertionAuthenticationToken.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAssertionAuthenticationToken.java index b0a2f718d..d04712d25 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAssertionAuthenticationToken.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAssertionAuthenticationToken.java @@ -18,19 +18,19 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio private String clientId; private JWT jwt; - + /** * Create an unauthenticated token with the given client ID and jwt * @param clientId * @param jwt */ public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt) { - super(null); - this.clientId = clientId; - this.jwt = jwt; - setAuthenticated(false); - } - + super(null); + this.clientId = clientId; + this.jwt = jwt; + setAuthenticated(false); + } + /** * Create an authenticated token with the given clientID, jwt, and authorities set * @param clientId @@ -38,11 +38,11 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio * @param authorities */ public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt, Collection authorities) { - super(authorities); - this.clientId = clientId; - this.jwt = jwt; - setAuthenticated(true); - } + super(authorities); + this.clientId = clientId; + this.jwt = jwt; + setAuthenticated(true); + } /* (non-Javadoc) * @see org.springframework.security.core.Authentication#getCredentials() @@ -61,42 +61,42 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio } /** - * @return the clientId - */ - public String getClientId() { - return clientId; - } + * @return the clientId + */ + public String getClientId() { + return clientId; + } /** - * @param clientId the clientId to set - */ - public void setClientId(String clientId) { - this.clientId = clientId; - } + * @param clientId the clientId to set + */ + public void setClientId(String clientId) { + this.clientId = clientId; + } /** - * @return the jwt - */ - public JWT getJwt() { - return jwt; - } + * @return the jwt + */ + public JWT getJwt() { + return jwt; + } /** - * @param jwt the jwt to set - */ - public void setJwt(JWT jwt) { - this.jwt = jwt; - } + * @param jwt the jwt to set + */ + public void setJwt(JWT jwt) { + this.jwt = jwt; + } /** * Clear out the JWT that this token holds. - */ - @Override - public void eraseCredentials() { - super.eraseCredentials(); - setJwt(null); - } - - + */ + @Override + public void eraseCredentials() { + super.eraseCredentials(); + setJwt(null); + } + + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAuthenticationProvider.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAuthenticationProvider.java index fa9adc2a1..ac2147090 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAuthenticationProvider.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerAuthenticationProvider.java @@ -36,49 +36,49 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { // map of verifiers, load keys for clients @Autowired private JWKSetSigningAndValidationServiceCacheService validators; - + // Allow for time sync issues by having a window of X seconds. private int timeSkewAllowance = 300; // to load clients @Autowired private ClientDetailsEntityService clientService; - + // to get our server's issuer url @Autowired private ConfigurationPropertiesBean config; - + /** * Try to validate the client credentials by parsing and validating the JWT. - */ - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - - JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication; - - - try { - ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId()); + */ + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { - JWT jwt = jwtAuth.getJwt(); - ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet(); + JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication; + + + try { + ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId()); + + JWT jwt = jwtAuth.getJwt(); + ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet(); + + // check the signature with nimbus + if (jwt instanceof SignedJWT) { + SignedJWT jws = (SignedJWT)jwt; + JwtSigningAndValidationService validator = validators.get(client.getJwksUri()); + if (validator == null || !validator.validateSignature(jws)) { + throw new AuthenticationServiceException("Invalid signature"); + } + } - // check the signature with nimbus - if (jwt instanceof SignedJWT) { - SignedJWT jws = (SignedJWT)jwt; - JwtSigningAndValidationService validator = validators.get(client.getJwksUri()); - if (validator == null || !validator.validateSignature(jws)) { - throw new AuthenticationServiceException("Invalid signature"); - } - } - // check the issuer if (jwtClaims.getIssuer() == null) { throw new AuthenticationServiceException("Assertion Token Issuer is null"); } else if (!jwtClaims.getIssuer().equals(client.getClientId())){ throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer()); } - + // check expiration if (jwtClaims.getExpirationTime() == null) { throw new AuthenticationServiceException("Assertion Token does not have required expiration claim"); @@ -89,7 +89,7 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpirationTime()); } } - + // check not before if (jwtClaims.getNotBeforeTime() != null) { Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); @@ -97,7 +97,7 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { throw new AuthenticationServiceException("Assertion Token not valid untill: " + jwtClaims.getNotBeforeTime()); } } - + // check issued at if (jwtClaims.getIssueTime() != null) { // since it's not null, see if it was issued in the future @@ -106,32 +106,32 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { throw new AuthenticationServiceException("Assertion Token was issued in the future: " + jwtClaims.getIssueTime()); } } - + // check audience if (jwtClaims.getAudience() == null) { - throw new AuthenticationServiceException("Assertion token audience is null"); + throw new AuthenticationServiceException("Assertion token audience is null"); } else if (!jwtClaims.getAudience().contains(config.getIssuer())) { throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " got " + jwtClaims.getAudience()); } - - // IFF we managed to get all the way down here, the token is valid + + // IFF we managed to get all the way down here, the token is valid return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, client.getAuthorities()); - - } catch (ClientNotFoundException e) { - throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId()); - } catch (ParseException e) { - // TODO Auto-generated catch block - throw new AuthenticationServiceException("Invalid JWT format"); - } - } + + } catch (ClientNotFoundException e) { + throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId()); + } catch (ParseException e) { + // TODO Auto-generated catch block + throw new AuthenticationServiceException("Invalid JWT format"); + } + } /** * We support {@link JwtBearerAssertionAuthenticationToken}s only. - */ - @Override - public boolean supports(Class authentication) { - return (JwtBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication)); - } + */ + @Override + public boolean supports(Class authentication) { + return (JwtBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication)); + } + - } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerClientAssertionTokenEndpointFilter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerClientAssertionTokenEndpointFilter.java index 2d1e5ecd9..07f52a692 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerClientAssertionTokenEndpointFilter.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JwtBearerClientAssertionTokenEndpointFilter.java @@ -28,74 +28,74 @@ import com.nimbusds.jwt.JWTParser; public class JwtBearerClientAssertionTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter { public JwtBearerClientAssertionTokenEndpointFilter() { - super(); - // TODO Auto-generated constructor stub - } + super(); + // TODO Auto-generated constructor stub + } public JwtBearerClientAssertionTokenEndpointFilter(String path) { - super(path); - // TODO Auto-generated constructor stub - } + super(path); + // TODO Auto-generated constructor stub + } /** * Pull the assertion out of the request and send it up to the auth manager for processing. - */ - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { + */ + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { - // check for appropriate parameters - String assertionType = request.getParameter("client_assertion_type"); - String assertion = request.getParameter("client_assertion"); - - try { - JWT jwt = JWTParser.parse(assertion); - - String clientId = jwt.getJWTClaimsSet().getSubject(); - - Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt); - - return this.getAuthenticationManager().authenticate(authRequest); - } catch (ParseException e) { - throw new BadCredentialsException("Invalid JWT credential: " + assertion); - } - } + // check for appropriate parameters + String assertionType = request.getParameter("client_assertion_type"); + String assertion = request.getParameter("client_assertion"); + + try { + JWT jwt = JWTParser.parse(assertion); + + String clientId = jwt.getJWTClaimsSet().getSubject(); + + Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt); + + return this.getAuthenticationManager().authenticate(authRequest); + } catch (ParseException e) { + throw new BadCredentialsException("Invalid JWT credential: " + assertion); + } + } /** * Check to see if the "client_assertion_type" and "client_assertion" parameters are present and contain the right values. - */ - @Override - protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { - // check for appropriate parameters - String assertionType = request.getParameter("client_assertion_type"); - String assertion = request.getParameter("client_assertion"); + */ + @Override + protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { + // check for appropriate parameters + String assertionType = request.getParameter("client_assertion_type"); + String assertion = request.getParameter("client_assertion"); + + if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) { + return false; + } else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) { + return false; + } + + + // Can't call to superclass here b/c client creds would break for lack of client_id + // return super.requiresAuthentication(request, response); + + String uri = request.getRequestURI(); + int pathParamIndex = uri.indexOf(';'); + + if (pathParamIndex > 0) { + // strip everything after the first semi-colon + uri = uri.substring(0, pathParamIndex); + } + + if ("".equals(request.getContextPath())) { + return uri.endsWith(getFilterProcessesUrl()); + } + + return uri.endsWith(request.getContextPath() + getFilterProcessesUrl()); + + } + - if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) { - return false; - } else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) { - return false; - } - - - // Can't call to superclass here b/c client creds would break for lack of client_id -// return super.requiresAuthentication(request, response); - - String uri = request.getRequestURI(); - int pathParamIndex = uri.indexOf(';'); - - if (pathParamIndex > 0) { - // strip everything after the first semi-colon - uri = uri.substring(0, pathParamIndex); - } - - if ("".equals(request.getContextPath())) { - return uri.endsWith(getFilterProcessesUrl()); - } - - return uri.endsWith(request.getContextPath() + getFilterProcessesUrl()); - - } - - } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/ExpiredTokenException.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/ExpiredTokenException.java index 2aa9118a6..c1de3ebcb 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/ExpiredTokenException.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/ExpiredTokenException.java @@ -30,5 +30,5 @@ public class ExpiredTokenException extends RuntimeException { public ExpiredTokenException(String message) { super(message); } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtIssuerException.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtIssuerException.java index c760393ff..11682bfc8 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtIssuerException.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtIssuerException.java @@ -30,5 +30,5 @@ public class InvalidJwtIssuerException extends RuntimeException { public InvalidJwtIssuerException(String message) { super(message); } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtSignatureException.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtSignatureException.java index c4dbd79f7..ba591774c 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtSignatureException.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/InvalidJwtSignatureException.java @@ -22,7 +22,7 @@ package org.mitre.openid.connect.exception; public class InvalidJwtSignatureException extends RuntimeException { private static final long serialVersionUID = 1L; - + public InvalidJwtSignatureException() { super(); } @@ -30,5 +30,5 @@ public class InvalidJwtSignatureException extends RuntimeException { public InvalidJwtSignatureException(String message) { super(message); } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UnknownUserInfoSchemaException.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UnknownUserInfoSchemaException.java index 766357122..cc956d354 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UnknownUserInfoSchemaException.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UnknownUserInfoSchemaException.java @@ -20,9 +20,9 @@ package org.mitre.openid.connect.exception; * */ public class UnknownUserInfoSchemaException extends RuntimeException { - + private static final long serialVersionUID = 1L; - + public UnknownUserInfoSchemaException() { super(); } @@ -30,5 +30,5 @@ public class UnknownUserInfoSchemaException extends RuntimeException { public UnknownUserInfoSchemaException(String message) { super(message); } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UserNotFoundException.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UserNotFoundException.java index 06e12d609..593d2caed 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UserNotFoundException.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/exception/UserNotFoundException.java @@ -5,23 +5,23 @@ public class UserNotFoundException extends RuntimeException { private static final long serialVersionUID = 1L; public UserNotFoundException() { - super(); - // TODO Auto-generated constructor stub - } + super(); + // TODO Auto-generated constructor stub + } public UserNotFoundException(String message, Throwable cause) { - super(message, cause); - // TODO Auto-generated constructor stub - } + super(message, cause); + // TODO Auto-generated constructor stub + } public UserNotFoundException(String message) { - super(message); - // TODO Auto-generated constructor stub - } + super(message); + // TODO Auto-generated constructor stub + } public UserNotFoundException(Throwable cause) { - super(cause); - // TODO Auto-generated constructor stub - } + super(cause); + // TODO Auto-generated constructor stub + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaApprovedSiteRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaApprovedSiteRepository.java index 5c8a54afb..74abc3f07 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaApprovedSiteRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaApprovedSiteRepository.java @@ -25,7 +25,6 @@ import javax.persistence.TypedQuery; import org.mitre.openid.connect.model.ApprovedSite; import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.util.jpa.JpaUtil; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -48,7 +47,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository { "ApprovedSite.getAll", ApprovedSite.class); return query.getResultList(); } - + @Override @Transactional public ApprovedSite getById(Long id) { @@ -59,7 +58,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository { @Transactional public void remove(ApprovedSite approvedSite) { ApprovedSite found = manager.find(ApprovedSite.class, approvedSite.getId()); - + if (found != null) { manager.remove(found); } else { @@ -75,30 +74,30 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository { @Override public Collection getByClientIdAndUserId(String clientId, String userId) { - + TypedQuery query = manager.createNamedQuery("ApprovedSite.getByClientIdAndUserId", ApprovedSite.class); query.setParameter("userId", userId); query.setParameter("clientId", clientId); - + return query.getResultList(); } - - @Override - @Transactional - public Collection getByUserId(String userId) { + + @Override + @Transactional + public Collection getByUserId(String userId) { TypedQuery query = manager.createNamedQuery("ApprovedSite.getByUserId", ApprovedSite.class); query.setParameter("userId", userId); return query.getResultList(); - - } - @Override - @Transactional - public Collection getByClientId(String clientId) { + } + + @Override + @Transactional + public Collection getByClientId(String clientId) { TypedQuery query = manager.createNamedQuery("ApprovedSite.getByClientId", ApprovedSite.class); query.setParameter("clientId", clientId); - + return query.getResultList(); - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaBlacklistedSiteRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaBlacklistedSiteRepository.java index 95cdbd849..1b6d20246 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaBlacklistedSiteRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaBlacklistedSiteRepository.java @@ -25,7 +25,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository { @PersistenceContext private EntityManager manager; - + /* (non-Javadoc) * @see org.mitre.openid.connect.repository.BlacklistedSiteRepository#getAll() */ @@ -52,7 +52,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository { @Transactional public void remove(BlacklistedSite blacklistedSite) { BlacklistedSite found = manager.find(BlacklistedSite.class, blacklistedSite.getId()); - + if (found != null) { manager.remove(found); } else { @@ -79,7 +79,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository { blacklistedSite.setId(oldBlacklistedSite.getId()); return saveOrUpdate(oldBlacklistedSite.getId(), manager, blacklistedSite); - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaEventRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaEventRepository.java index f9d0aca88..dded69867 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaEventRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaEventRepository.java @@ -38,7 +38,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Repository public class JpaEventRepository implements EventRepository { - + @PersistenceContext private EntityManager manager; @@ -52,17 +52,17 @@ public class JpaEventRepository implements EventRepository { @Override @Transactional public Collection getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize) { - + Query query = manager.createQuery("SELECT e FROM Event e WHERE e.timestamp BETWEEN :start AND :end"); - + query = query.setParameter("start", start, TemporalType.DATE); query = query.setParameter("end", end, TemporalType.DATE); query = query.setFirstResult(startChunk); - query = query.setMaxResults(chunkSize); - + query = query.setMaxResults(chunkSize); + return query.getResultList(); } - + @Override @Transactional public void remove(Event event) { diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaNonceRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaNonceRepository.java index b89e62d4b..4cc89cc9a 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaNonceRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaNonceRepository.java @@ -8,7 +8,6 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery; -import org.mitre.openid.connect.model.ApprovedSite; import org.mitre.openid.connect.model.Nonce; import org.mitre.openid.connect.repository.NonceRepository; import org.springframework.stereotype.Repository; @@ -20,7 +19,7 @@ public class JpaNonceRepository implements NonceRepository { @PersistenceContext private EntityManager manager; - + @Override @Transactional public Nonce getById(Long id) { @@ -31,7 +30,7 @@ public class JpaNonceRepository implements NonceRepository { @Transactional public void remove(Nonce nonce) { Nonce found = manager.find(Nonce.class, nonce.getId()); - + if (found != null) { manager.remove(found); } else { @@ -65,7 +64,7 @@ public class JpaNonceRepository implements NonceRepository { public Collection getByClientId(String clientId) { TypedQuery query = manager.createNamedQuery("Nonce.getByClientId", Nonce.class); query.setParameter("clientId", clientId); - + return query.getResultList(); } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java index 290b13585..6c31139d6 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java @@ -15,8 +15,8 @@ ******************************************************************************/ package org.mitre.openid.connect.repository.impl; -import static org.mitre.util.jpa.JpaUtil.saveOrUpdate; import static org.mitre.util.jpa.JpaUtil.getSingleResult; +import static org.mitre.util.jpa.JpaUtil.saveOrUpdate; import java.util.Collection; @@ -40,43 +40,43 @@ import org.springframework.transaction.annotation.Transactional; public class JpaUserInfoRepository implements UserInfoRepository { @PersistenceContext - private EntityManager manager; - + private EntityManager manager; + @Override - @Transactional + @Transactional public UserInfo getBySubject(String sub) { TypedQuery query = manager.createNamedQuery("DefaultUserInfo.getBySubject", DefaultUserInfo.class); query.setParameter("sub", sub); - + return getSingleResult(query.getResultList()); - } - + } + @Override - @Transactional + @Transactional public UserInfo save(UserInfo userInfo) { DefaultUserInfo dui = (DefaultUserInfo)userInfo; return saveOrUpdate(dui.getId(), manager, dui); } @Override - @Transactional + @Transactional public void remove(UserInfo userInfo) { DefaultUserInfo dui = (DefaultUserInfo)userInfo; UserInfo found = manager.find(DefaultUserInfo.class, dui.getId()); - + if (found != null) { manager.remove(userInfo); } else { throw new IllegalArgumentException(); - } + } } @Override - @Transactional + @Transactional public Collection getAll() { - + TypedQuery query = manager.createNamedQuery("DefaultUserInfo.getAll", DefaultUserInfo.class); - + return query.getResultList(); } @@ -84,12 +84,12 @@ public class JpaUserInfoRepository implements UserInfoRepository { * Get a single UserInfo object by its username */ @Override - public UserInfo getByUsername(String username) { + public UserInfo getByUsername(String username) { TypedQuery query = manager.createNamedQuery("DefaultUserInfo.getByUsername", DefaultUserInfo.class); query.setParameter("username", username); - + return getSingleResult(query.getResultList()); - - } + + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaWhitelistedSiteRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaWhitelistedSiteRepository.java index db32154ec..6ba4b8b51 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaWhitelistedSiteRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaWhitelistedSiteRepository.java @@ -77,10 +77,10 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository { public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite) { // sanity check whitelistedSite.setId(oldWhitelistedSite.getId()); - + return saveOrUpdate(oldWhitelistedSite.getId(), manager, whitelistedSite); } - + @Override @Transactional public WhitelistedSite getByClientId(String clientId) { @@ -94,7 +94,7 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository { public Collection getByCreator(String creatorId) { TypedQuery query = manager.createNamedQuery("WhitelistedSite.getByCreaterUserId", WhitelistedSite.class); query.setParameter("userId", creatorId); - + return query.getResultList(); } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java index 7217b4c6f..a07ac2f2f 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java @@ -42,26 +42,26 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { @Autowired private ApprovedSiteRepository approvedSiteRepository; - + @Autowired private OAuth2TokenRepository tokenRepository; /** * Default constructor - */ + */ public DefaultApprovedSiteService() { } - - /** - * Constructor for use in test harnesses. - * - * @param repository - */ + + /** + * Constructor for use in test harnesses. + * + * @param repository + */ public DefaultApprovedSiteService(ApprovedSiteRepository approvedSiteRepository) { this.approvedSiteRepository = approvedSiteRepository; - } - + } + @Override public Collection getAll() { return approvedSiteRepository.getAll(); @@ -81,7 +81,7 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { @Override @Transactional public void remove(ApprovedSite approvedSite) { - + //Remove any associated access and refresh tokens Set accessTokens = approvedSite.getApprovedAccessTokens(); @@ -91,17 +91,17 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { } tokenRepository.removeAccessToken(token); } - + approvedSiteRepository.remove(approvedSite); } @Override @Transactional public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set allowedScopes, - WhitelistedSite whitelistedSite) { - + WhitelistedSite whitelistedSite) { + ApprovedSite as = approvedSiteRepository.save(new ApprovedSite()); - + Date now = new Date(); as.setCreationDate(now); as.setAccessDate(now); @@ -110,47 +110,47 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { as.setTimeoutDate(timeoutDate); as.setAllowedScopes(allowedScopes); as.setWhitelistedSite(whitelistedSite); - + return save(as); - + } @Override public Collection getByClientIdAndUserId(String clientId, String userId) { - + return approvedSiteRepository.getByClientIdAndUserId(clientId, userId); - + } /** - * @param userId - * @return - * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String) - */ + * @param userId + * @return + * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String) + */ @Override - public Collection getByUserId(String userId) { - return approvedSiteRepository.getByUserId(userId); - } + public Collection getByUserId(String userId) { + return approvedSiteRepository.getByUserId(userId); + } /** - * @param clientId - * @return - * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String) - */ + * @param clientId + * @return + * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String) + */ @Override - public Collection getByClientId(String clientId) { - return approvedSiteRepository.getByClientId(clientId); - } + public Collection getByClientId(String clientId) { + return approvedSiteRepository.getByClientId(clientId); + } @Override public void clearApprovedSitesForClient(ClientDetails client) { - Collection approvedSites = approvedSiteRepository.getByClientId(client.getClientId()); + Collection approvedSites = approvedSiteRepository.getByClientId(client.getClientId()); if (approvedSites != null) { for (ApprovedSite approvedSite : approvedSites) { - approvedSiteRepository.remove(approvedSite); - } + approvedSiteRepository.remove(approvedSite); + } } - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultBlacklistedSiteService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultBlacklistedSiteService.java index 96c5590d3..f4b58b395 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultBlacklistedSiteService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultBlacklistedSiteService.java @@ -24,7 +24,7 @@ public class DefaultBlacklistedSiteService implements BlacklistedSiteService { @Autowired private BlacklistedSiteRepository repository; - + /* (non-Javadoc) * @see org.mitre.openid.connect.service.BlacklistedSiteService#getAll() */ @@ -70,21 +70,21 @@ public class DefaultBlacklistedSiteService implements BlacklistedSiteService { */ @Override public boolean isBlacklisted(String uri) { - + if (Strings.isNullOrEmpty(uri)) { return false; // can't be blacklisted if you don't exist } - + Collection sites = getAll(); // TODO: rewrite this to do regex matching and use the Guava predicates collection - + for (BlacklistedSite blacklistedSite : sites) { - if (Strings.nullToEmpty(blacklistedSite.getUri()).equals(uri)) { - return true; - } - } - + if (Strings.nullToEmpty(blacklistedSite.getUri()).equals(uri)) { + return true; + } + } + return false; } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultNonceService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultNonceService.java index b29d54082..e040e7461 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultNonceService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultNonceService.java @@ -18,17 +18,18 @@ import org.springframework.stereotype.Service; @Service("defaultNonceService") public class DefaultNonceService implements NonceService, InitializingBean { - private static Logger logger = LoggerFactory.getLogger(NonceService.class); - + private static Logger logger = LoggerFactory.getLogger(NonceService.class); + @Autowired private NonceRepository repository; - + @Autowired private Period nonceStorageDuration; - + /** * Make sure that the nonce storage duration was set */ + @Override public void afterPropertiesSet() throws Exception { if (nonceStorageDuration == null) { logger.error("Nonce storage duration must be set!"); @@ -51,7 +52,7 @@ public class DefaultNonceService implements NonceService, InitializingBean { @Override public boolean alreadyUsed(String clientId, String value) { - + Collection clientNonces = getByClientId(clientId); for (Nonce nonce : clientNonces) { String nonceVal = nonce.getValue(); @@ -59,10 +60,10 @@ public class DefaultNonceService implements NonceService, InitializingBean { return true; } } - + return false; } - + @Override public Nonce getById(Long id) { return repository.getById(id); @@ -92,16 +93,16 @@ public class DefaultNonceService implements NonceService, InitializingBean { public Collection getByClientId(String clientId) { return repository.getByClientId(clientId); } - + @Override @Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes public void clearExpiredNonces() { - + logger.info("Clearing expired nonces"); - + Collection expired = repository.getExpired(); logger.info("Found " + expired.size() + " expired nonces"); - + for (Nonce nonce : expired) { remove(nonce); } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultStatsService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultStatsService.java index 71189d0b1..08f3a4378 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultStatsService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultStatsService.java @@ -24,26 +24,26 @@ public class DefaultStatsService implements StatsService { @Autowired private ApprovedSiteService approvedSiteService; - + @Override - public Map calculateSummaryStats() { - // get all approved sites - Collection allSites = approvedSiteService.getAll(); - - // process to find number of unique users and sites - Set userIds = new HashSet(); - Set clientIds = new HashSet(); - for (ApprovedSite approvedSite : allSites) { - userIds.add(approvedSite.getUserId()); - clientIds.add(approvedSite.getClientId()); - } - - Map e = new HashMap(); - - e.put("approvalCount", allSites.size()); - e.put("userCount", userIds.size()); - e.put("clientCount", clientIds.size()); - return e; - } + public Map calculateSummaryStats() { + // get all approved sites + Collection allSites = approvedSiteService.getAll(); + + // process to find number of unique users and sites + Set userIds = new HashSet(); + Set clientIds = new HashSet(); + for (ApprovedSite approvedSite : allSites) { + userIds.add(approvedSite.getUserId()); + clientIds.add(approvedSite.getClientId()); + } + + Map e = new HashMap(); + + e.put("approvalCount", allSites.size()); + e.put("userCount", userIds.size()); + e.put("clientCount", clientIds.size()); + return e; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java index 6aac2fbe0..71aa8d631 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java @@ -70,19 +70,19 @@ public class DefaultUserInfoService implements UserInfoService { public UserInfo getByUsername(String username) { return userInfoRepository.getByUsername(username); } - - /** - * @return the userInfoRepository - */ - public UserInfoRepository getUserInfoRepository() { - return userInfoRepository; - } /** - * @param userInfoRepository the userInfoRepository to set - */ - public void setUserInfoRepository(UserInfoRepository userInfoRepository) { - this.userInfoRepository = userInfoRepository; - } + * @return the userInfoRepository + */ + public UserInfoRepository getUserInfoRepository() { + return userInfoRepository; + } + + /** + * @param userInfoRepository the userInfoRepository to set + */ + public void setUserInfoRepository(UserInfoRepository userInfoRepository) { + this.userInfoRepository = userInfoRepository; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoUserDetailsService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoUserDetailsService.java index 0ae3be212..ed42c1916 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoUserDetailsService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoUserDetailsService.java @@ -16,38 +16,38 @@ import org.springframework.stereotype.Service; /** * A UserDetailsService backed by a UserInfoRepository. - * + * * @author jricher * */ @Service("userInfoUserDetailsService") public class DefaultUserInfoUserDetailsService implements UserDetailsService { - + @Autowired UserInfoRepository repository; - - public static final GrantedAuthority ROLE_USER = new SimpleGrantedAuthority("ROLE_USER"); - public static final GrantedAuthority ROLE_ADMIN = new SimpleGrantedAuthority("ROLE_ADMIN"); - private List admins = new ArrayList(); - + public static final GrantedAuthority ROLE_USER = new SimpleGrantedAuthority("ROLE_USER"); + public static final GrantedAuthority ROLE_ADMIN = new SimpleGrantedAuthority("ROLE_ADMIN"); + + private List admins = new ArrayList(); + @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = repository.getByUsername(username); - + if (userInfo != null) { - + // TODO: make passwords configurable? part of object? String password = "password"; - - List authorities = new ArrayList(); - authorities.add(ROLE_USER); - - if (admins != null && admins.contains(username)) { - authorities.add(ROLE_ADMIN); - } - - // TODO: this should really be our own UserDetails wrapper class, shouldn't it? + + List authorities = new ArrayList(); + authorities.add(ROLE_USER); + + if (admins != null && admins.contains(username)) { + authorities.add(ROLE_ADMIN); + } + + // TODO: this should really be our own UserDetails wrapper class, shouldn't it? User user = new User(userInfo.getSub(), password, authorities); return user; } else { @@ -56,17 +56,17 @@ public class DefaultUserInfoUserDetailsService implements UserDetailsService { } /** - * @return the admins - */ - public List getAdmins() { - return admins; - } + * @return the admins + */ + public List getAdmins() { + return admins; + } /** - * @param admins the admins to set - */ - public void setAdmins(List admins) { - this.admins = admins; - } + * @param admins the admins to set + */ + public void setAdmins(List admins) { + this.admins = admins; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultWhitelistedSiteService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultWhitelistedSiteService.java index 6cfd710c5..c25e9a7da 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultWhitelistedSiteService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultWhitelistedSiteService.java @@ -51,8 +51,8 @@ public class DefaultWhitelistedSiteService implements WhitelistedSiteService { */ public DefaultWhitelistedSiteService(WhitelistedSiteRepository whitelistedSiteRepository) { this.repository = whitelistedSiteRepository; - } - + } + @Override public WhitelistedSite getById(Long id) { return repository.getById(id); @@ -86,12 +86,12 @@ public class DefaultWhitelistedSiteService implements WhitelistedSiteService { return repository.getByCreator(creatorId); } - @Override - public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite) { - if (oldWhitelistedSite == null || whitelistedSite == null) { - throw new IllegalArgumentException("Neither the old or new sites may be null"); - } - return repository.update(oldWhitelistedSite, whitelistedSite); - } + @Override + public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite) { + if (oldWhitelistedSite == null || whitelistedSite == null) { + throw new IllegalArgumentException("Neither the old or new sites may be null"); + } + return repository.update(oldWhitelistedSite, whitelistedSite); + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java index 934b18c58..3d0b82905 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java @@ -45,81 +45,81 @@ import com.nimbusds.jwt.SignedJWT; public class ConnectTokenEnhancer implements TokenEnhancer { Logger logger = LoggerFactory.getLogger(ConnectTokenEnhancer.class); - + @Autowired private ConfigurationPropertiesBean configBean; - + @Autowired private JwtSigningAndValidationService jwtService; - + @Autowired private ClientDetailsEntityService clientService; - + @Autowired private ApprovedSiteService approvedSiteService; - + @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { - + OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) accessToken; OAuth2Request originalAuthRequest = authentication.getOAuth2Request(); - + String clientId = originalAuthRequest.getClientId(); ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - + JWTClaimsSet claims = new JWTClaimsSet(); - + claims.setAudience(Lists.newArrayList(clientId)); - + claims.setIssuer(configBean.getIssuer()); claims.setIssueTime(new Date()); - + claims.setExpirationTime(token.getExpiration()); claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it - + // TODO: use client's default signing algorithm SignedJWT signed = new SignedJWT(new JWSHeader(jwtService.getDefaultSigningAlgorithm()), claims); - - jwtService.signJwt(signed); - - token.setJwt(signed); - + + jwtService.signJwt(signed); + + token.setJwt(signed); + /** - * Authorization request scope MUST include "openid" in OIDC, but access token request - * may or may not include the scope parameter. As long as the AuthorizationRequest + * Authorization request scope MUST include "openid" in OIDC, but access token request + * may or may not include the scope parameter. As long as the AuthorizationRequest * has the proper scope, we can consider this a valid OpenID Connect request. Otherwise, - * we consider it to be a vanilla OAuth2 request. + * we consider it to be a vanilla OAuth2 request. */ if (originalAuthRequest.getScope().contains("openid")) { // TODO: maybe id tokens need a service layer - + String userId = authentication.getName(); - + OAuth2AccessTokenEntity idTokenEntity = new OAuth2AccessTokenEntity(); - + // FIXME: extend the "claims" section for id tokens JWTClaimsSet idClaims = new JWTClaimsSet(); - - + + idClaims.setCustomClaim("auth_time", new Date().getTime()); - + idClaims.setIssueTime(new Date()); - + if (client.getIdTokenValiditySeconds() != null) { Date expiration = new Date(System.currentTimeMillis() + (client.getIdTokenValiditySeconds() * 1000L)); idClaims.setExpirationTime(expiration); idTokenEntity.setExpiration(expiration); } - + idClaims.setIssuer(configBean.getIssuer()); idClaims.setSubject(userId); idClaims.setAudience(Lists.newArrayList(clientId)); - - + + String nonce = originalAuthRequest.getRequestParameters().get("nonce"); if (!Strings.isNullOrEmpty(nonce)) { idClaims.setCustomClaim("nonce", nonce); @@ -128,11 +128,11 @@ public class ConnectTokenEnhancer implements TokenEnhancer { SignedJWT idToken = new SignedJWT(new JWSHeader(jwtService.getDefaultSigningAlgorithm()), idClaims); //TODO: check for client's preferred signer alg and use that - + jwtService.signJwt(idToken); idTokenEntity.setJwt(idToken); - + // TODO: might want to create a specialty authentication object here instead of copying idTokenEntity.setAuthenticationHolder(token.getAuthenticationHolder()); @@ -140,14 +140,14 @@ public class ConnectTokenEnhancer implements TokenEnhancer { //Set idScopes = new HashSet(token.getScope()); // this would copy the original token's scopes in, we don't really want that Set idScopes = Sets.newHashSet(OAuth2AccessTokenEntity.ID_TOKEN_SCOPE); idTokenEntity.setScope(idScopes); - + idTokenEntity.setClient(token.getClient()); - + // attach the id token to the parent access token // TODO: this relationship is one-to-one right now, this might change token.setIdToken(idTokenEntity); } - + return token; } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java index a48f5c6a0..d2caadcf3 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java @@ -37,14 +37,14 @@ import com.google.common.base.Strings; import com.google.common.collect.Sets; /** - * Custom User Approval Handler implementation which uses a concept of a whitelist, - * blacklist, and greylist. + * Custom User Approval Handler implementation which uses a concept of a whitelist, + * blacklist, and greylist. * - * Blacklisted sites will be caught and handled before this - * point. + * Blacklisted sites will be caught and handled before this + * point. * * Whitelisted sites will be automatically approved, and an ApprovedSite entry will - * be created for the site the first time a given user access it. + * be created for the site the first time a given user access it. * * All other sites fall into the greylist - the user will be presented with the user * approval page upon their first visit @@ -53,31 +53,31 @@ import com.google.common.collect.Sets; */ @Component("tofuUserApprovalHandler") public class TofuUserApprovalHandler implements UserApprovalHandler { - + @Autowired private ApprovedSiteService approvedSiteService; - + @Autowired private WhitelistedSiteService whitelistedSiteService; - + @Autowired private ClientDetailsService clientDetailsService; - - + + @Override public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { - + // if this request is already approved, pass that info through // (this flag may be set by updateBeforeApproval, which can also do funny things with scopes, etc) if (authorizationRequest.isApproved()) { return true; } else { // if not, check to see if the user has approved it - + // TODO: make parameter name configurable? boolean approved = Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval")); - + return userAuthentication.isAuthenticated() && approved; } @@ -89,16 +89,16 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { * * Otherwise the user will be directed to the approval page and can make their own decision. * - * @param authorizationRequest the incoming authorization request + * @param authorizationRequest the incoming authorization request * @param userAuthentication the Principal representing the currently-logged-in user * * @return the updated AuthorizationRequest */ @Override public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { - + //First, check database to see if the user identified by the userAuthentication has stored an approval decision - + //getName may not be filled in? TODO: investigate String userId = userAuthentication.getName(); String clientId = authorizationRequest.getClientId(); @@ -107,67 +107,67 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { boolean alreadyApproved = false; Collection aps = approvedSiteService.getByClientIdAndUserId(clientId, userId); for (ApprovedSite ap : aps) { - + if (!ap.isExpired()) { - + // if we find one that fits... if (scopesMatch(authorizationRequest.getScope(), ap.getAllowedScopes())) { - + //We have a match; update the access date on the AP entry and return true. ap.setAccessDate(new Date()); approvedSiteService.save(ap); - + authorizationRequest.getExtensions().put("approved_site", ap.getId()); - authorizationRequest.setApproved(true); + authorizationRequest.setApproved(true); alreadyApproved = true; } } - } - + } + if (!alreadyApproved) { WhitelistedSite ws = whitelistedSiteService.getByClientId(clientId); if (ws != null && scopesMatch(authorizationRequest.getScope(), ws.getAllowedScopes())) { - + //Create an approved site - ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, null, ws.getAllowedScopes(), ws); + ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, null, ws.getAllowedScopes(), ws); authorizationRequest.getExtensions().put("approved_site", newSite.getId()); authorizationRequest.setApproved(true); } } - + return authorizationRequest; - + } - + @Override - public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { String userId = userAuthentication.getName(); String clientId = authorizationRequest.getClientId(); ClientDetails client = clientDetailsService.loadClientByClientId(clientId); - + // This must be re-parsed here because SECOAUTH forces us to call things in a strange order boolean approved = Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval")); - + if (approved) { - + authorizationRequest.setApproved(true); - + // process scopes from user input Set allowedScopes = Sets.newHashSet(); Map approvalParams = authorizationRequest.getApprovalParameters(); - + Set keys = approvalParams.keySet(); - + for (String key : keys) { if (key.startsWith("scope_")) { //This is a scope parameter from the approval page. The value sent back should - //be the scope string. Check to make sure it is contained in the client's + //be the scope string. Check to make sure it is contained in the client's //registered allowed scopes. - + String scope = approvalParams.get(key); - + //Make sure this scope is allowed for the given client if (client.getScope().contains(scope)) { allowedScopes.add(scope); @@ -178,11 +178,11 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { // inject the user-allowed scopes into the auth request // TODO: for the moment this allows both upscoping and downscoping. authorizationRequest.setScope(allowedScopes); - + //Only store an ApprovedSite if the user has checked "remember this decision": String remember = authorizationRequest.getApprovalParameters().get("remember"); if (!Strings.isNullOrEmpty(remember) && !remember.equals("none")) { - + Date timeout = null; if (remember.equals("one-hour")) { // set the timeout to one hour from now @@ -190,16 +190,16 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { cal.add(Calendar.HOUR, 1); timeout = cal.getTime(); } - + ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, timeout, allowedScopes, null); authorizationRequest.getExtensions().put("approved_site", newSite.getId()); } - + } return authorizationRequest; - } - + } + /** * Check whether the requested scope set is a proper subset of the allowed scopes. * @@ -208,15 +208,15 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { * @return */ private boolean scopesMatch(Set requestedScopes, Set allowedScopes) { - + for (String scope : requestedScopes) { - + if (!allowedScopes.contains(scope)) { return false; //throw new InvalidScopeException("Invalid scope: " + scope, allowedScopes); } } - + return true; } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/AbstractClientEntityView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/AbstractClientEntityView.java index 8e1b1f89c..7eadee104 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/AbstractClientEntityView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/AbstractClientEntityView.java @@ -17,11 +17,9 @@ import org.mitre.jose.JWSAlgorithmEmbed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; -import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.web.servlet.view.AbstractView; import com.google.gson.ExclusionStrategy; -import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; @@ -43,71 +41,72 @@ public abstract class AbstractClientEntityView extends AbstractView { private static Logger logger = LoggerFactory.getLogger(ClientEntityViewForAdmins.class); private Gson gson = new GsonBuilder() - .setExclusionStrategies(getExclusionStrategy()) - .registerTypeAdapter(JWSAlgorithmEmbed.class, new JsonSerializer() { - @Override - public JsonElement serialize(JWSAlgorithmEmbed src, Type typeOfSrc, JsonSerializationContext context) { - if (src != null) { - return new JsonPrimitive(src.getAlgorithmName()); - } else { - return null; - } - } - }) - .registerTypeAdapter(JWEAlgorithmEmbed.class, new JsonSerializer() { - @Override - public JsonElement serialize(JWEAlgorithmEmbed src, Type typeOfSrc, JsonSerializationContext context) { - if (src != null) { - return new JsonPrimitive(src.getAlgorithmName()); - } else { - return null; - } - } - }) - .registerTypeAdapter(JWEEncryptionMethodEmbed.class, new JsonSerializer() { - @Override - public JsonElement serialize(JWEEncryptionMethodEmbed src, Type typeOfSrc, JsonSerializationContext context) { - if (src != null) { - return new JsonPrimitive(src.getAlgorithmName()); - } else { - return null; - } - } - }) - .serializeNulls() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .create(); + .setExclusionStrategies(getExclusionStrategy()) + .registerTypeAdapter(JWSAlgorithmEmbed.class, new JsonSerializer() { + @Override + public JsonElement serialize(JWSAlgorithmEmbed src, Type typeOfSrc, JsonSerializationContext context) { + if (src != null) { + return new JsonPrimitive(src.getAlgorithmName()); + } else { + return null; + } + } + }) + .registerTypeAdapter(JWEAlgorithmEmbed.class, new JsonSerializer() { + @Override + public JsonElement serialize(JWEAlgorithmEmbed src, Type typeOfSrc, JsonSerializationContext context) { + if (src != null) { + return new JsonPrimitive(src.getAlgorithmName()); + } else { + return null; + } + } + }) + .registerTypeAdapter(JWEEncryptionMethodEmbed.class, new JsonSerializer() { + @Override + public JsonElement serialize(JWEEncryptionMethodEmbed src, Type typeOfSrc, JsonSerializationContext context) { + if (src != null) { + return new JsonPrimitive(src.getAlgorithmName()); + } else { + return null; + } + } + }) + .serializeNulls() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); /** * @return */ - protected abstract ExclusionStrategy getExclusionStrategy(); - - - protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { + protected abstract ExclusionStrategy getExclusionStrategy(); - response.setContentType("application/json"); - - HttpStatus code = (HttpStatus) model.get("code"); - if (code == null) { - code = HttpStatus.OK; // default to 200 - } - - response.setStatus(code.value()); - - try { - - Writer out = response.getWriter(); - Object obj = model.get("entity"); - gson.toJson(obj, out); - - } catch (IOException e) { - - logger.error("IOException in JsonEntityView.java: ", e); - - } - } + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { + + response.setContentType("application/json"); + + + HttpStatus code = (HttpStatus) model.get("code"); + if (code == null) { + code = HttpStatus.OK; // default to 200 + } + + response.setStatus(code.value()); + + try { + + Writer out = response.getWriter(); + Object obj = model.get("entity"); + gson.toJson(obj, out); + + } catch (IOException e) { + + logger.error("IOException in JsonEntityView.java: ", e); + + } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForAdmins.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForAdmins.java index 236fad60a..246e236a3 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForAdmins.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForAdmins.java @@ -3,34 +3,14 @@ */ package org.mitre.openid.connect.view; -import java.io.IOException; -import java.io.Writer; -import java.lang.reflect.Type; -import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.mitre.jose.JWEAlgorithmEmbed; -import org.mitre.jose.JWEEncryptionMethodEmbed; -import org.mitre.jose.JWSAlgorithmEmbed; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.web.servlet.view.AbstractView; import com.google.common.collect.ImmutableSet; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; /** * @@ -44,29 +24,32 @@ import com.google.gson.JsonSerializer; public class ClientEntityViewForAdmins extends AbstractClientEntityView { private Set blacklistedFields = ImmutableSet.of("additionalInformation"); - + /** * @return */ - protected ExclusionStrategy getExclusionStrategy() { - return new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - if (blacklistedFields.contains(f.getName())) { - return true; - } else { - return false; - } - } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }; - } + @Override + protected ExclusionStrategy getExclusionStrategy() { + return new ExclusionStrategy() { + + @Override + public boolean shouldSkipField(FieldAttributes f) { + if (blacklistedFields.contains(f.getName())) { + return true; + } else { + return false; + } + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; + } + return false; + } + + }; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForUsers.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForUsers.java index a7f1099a5..02e14f9dc 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForUsers.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientEntityViewForUsers.java @@ -3,38 +3,18 @@ */ package org.mitre.openid.connect.view; -import java.io.IOException; -import java.io.Writer; -import java.lang.reflect.Type; -import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.mitre.jose.JWEAlgorithmEmbed; -import org.mitre.jose.JWEEncryptionMethodEmbed; -import org.mitre.jose.JWSAlgorithmEmbed; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.web.servlet.view.AbstractView; import com.google.common.collect.ImmutableSet; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; /** * - * View bean for field-limited view of client entity, for regular users. + * View bean for field-limited view of client entity, for regular users. * * @see AbstractClientEntityView * @see ClientEntityViewForAdmins @@ -45,32 +25,34 @@ import com.google.gson.JsonSerializer; public class ClientEntityViewForUsers extends AbstractClientEntityView { private Set whitelistedFields = ImmutableSet.of("clientName", "clientId", "id", "clientDescription", "scope", "logoUri"); - + /* (non-Javadoc) * @see org.mitre.openid.connect.view.AbstractClientEntityView#getExclusionStrategy() */ - @Override - protected ExclusionStrategy getExclusionStrategy() { - return new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - // whitelist the handful of fields that are good - if (whitelistedFields.contains(f.getName())) { - return false; - } else { - return true; - } - } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }; - } - + @Override + protected ExclusionStrategy getExclusionStrategy() { + return new ExclusionStrategy() { + + @Override + public boolean shouldSkipField(FieldAttributes f) { + // whitelist the handful of fields that are good + if (whitelistedFields.contains(f.getName())) { + return false; + } else { + return true; + } + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; + } + return false; + } + + }; + } + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientInformationResponseView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientInformationResponseView.java index fd103c91c..ca62834ee 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientInformationResponseView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ClientInformationResponseView.java @@ -37,7 +37,7 @@ public class ClientInformationResponseView extends AbstractView { // note that this won't serialize nulls by default private Gson gson = new Gson(); - + /* (non-Javadoc) * @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @@ -45,35 +45,35 @@ public class ClientInformationResponseView extends AbstractView { protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/json"); - + ClientDetailsEntity c = (ClientDetailsEntity) model.get("client"); OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) model.get("token"); HttpStatus code = (HttpStatus) model.get("code"); if (code == null) { code = HttpStatus.OK; } - + JsonObject o = new JsonObject(); - + o.addProperty("client_id", c.getClientId()); if (c.getClientSecret() != null) { o.addProperty("client_secret", c.getClientSecret()); o.addProperty("expires_at", 0); // TODO: do we want to let secrets expire? } - + if (c.getCreatedAt() != null) { o.addProperty("issued_at", c.getCreatedAt().getTime()); } o.addProperty("registration_access_token", token.getValue()); - + // TODO: urlencode the client id for safety? - String uri = request.getRequestURL() + "/" + c.getClientId(); + String uri = request.getRequestURL() + "/" + c.getClientId(); o.addProperty("registration_client_uri", uri); - - + + // add in all other client properties - + // OAuth DynReg o.add("redirect_uris", getAsArray(c.getRedirectUris())); o.addProperty("client_name", c.getClientName()); @@ -86,7 +86,7 @@ public class ClientInformationResponseView extends AbstractView { o.add("grant_types", getAsArray(c.getGrantTypes())); o.addProperty("policy_uri", c.getPolicyUri()); o.addProperty("jwks_uri", c.getJwksUri()); - + // OIDC Registration o.addProperty("application_type", c.getApplicationType() != null ? c.getApplicationType().getValue() : null); o.addProperty("sector_identifier_uri", c.getSectorIdentifierUri()); @@ -104,20 +104,20 @@ public class ClientInformationResponseView extends AbstractView { o.addProperty("initiate_login_uri", c.getInitiateLoginUri()); o.addProperty("post_logout_redirect_uri", c.getPostLogoutRedirectUri()); o.add("request_uris", getAsArray(c.getRequestUris())); - + try { - Writer out = response.getWriter(); - gson.toJson(o, out); - } catch (JsonIOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - + Writer out = response.getWriter(); + gson.toJson(o, out); + } catch (JsonIOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } - + private JsonElement getAsArray(Set value) { return gson.toJsonTree(value, new TypeToken>(){}.getType()); } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ExceptionAsJSONView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ExceptionAsJSONView.java index c3f057175..bb97418d5 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ExceptionAsJSONView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/ExceptionAsJSONView.java @@ -37,7 +37,7 @@ import com.google.gson.JsonObject; public class ExceptionAsJSONView extends AbstractView { private static Logger logger = LoggerFactory.getLogger(ExceptionAsJSONView.class); - + /* * (non-Javadoc) * @@ -52,7 +52,7 @@ public class ExceptionAsJSONView extends AbstractView { response.setContentType("application/json"); response.setStatus(HttpStatus.BAD_REQUEST.value()); - + final JsonObject jsonObject = new JsonObject(); Object ex = model.get("exception"); @@ -62,13 +62,13 @@ public class ExceptionAsJSONView extends AbstractView { ((Exception) ex).getMessage()); try { - + response.getWriter().write(jsonObject.toString()); - + } catch (IOException e) { - + logger.error("IOException in ExceptionAsJSONView.java: ", e); - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/HttpCodeView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/HttpCodeView.java index 47a926cff..ac0f671b9 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/HttpCodeView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/HttpCodeView.java @@ -26,9 +26,9 @@ public class HttpCodeView extends AbstractView { if (code == null) { code = HttpStatus.OK; // default to 200 } - + response.setStatus(code.value()); - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JSONUserInfoView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JSONUserInfoView.java index eac1e3fc3..99a635a83 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JSONUserInfoView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JSONUserInfoView.java @@ -49,87 +49,90 @@ import com.nimbusds.jwt.JWTParser; @Component("jsonUserInfoView") public class JSONUserInfoView extends AbstractView { - + private static Logger logger = LoggerFactory.getLogger(JSONUserInfoView.class); - + /* (non-Javadoc) * @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ + @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { - + UserInfo userInfo = (UserInfo) model.get("userInfo"); Set scope = (Set) model.get("scope"); - + Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - - return false; + .setExclusionStrategies(new ExclusionStrategy() { + + @Override + public boolean shouldSkipField(FieldAttributes f) { + + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }).create(); + return false; + } + + }).create(); response.setContentType("application/json"); - + Writer out; - + try { - + out = response.getWriter(); - + if (model.get("requestObject") != null) { - + try { - String jwtString = (String)model.get("requestObject"); - JWT requestObject = JWTParser.parse(jwtString); - - // FIXME: move to GSON for easier processing - JsonObject obj = (JsonObject) new JsonParser().parse(requestObject.getJWTClaimsSet().toJSONObject().toJSONString()); - - gson.toJson(toJsonFromRequestObj(userInfo, scope, obj), out); - } catch (JsonSyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (JsonIOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - + String jwtString = (String)model.get("requestObject"); + JWT requestObject = JWTParser.parse(jwtString); + + // FIXME: move to GSON for easier processing + JsonObject obj = (JsonObject) new JsonParser().parse(requestObject.getJWTClaimsSet().toJSONObject().toJSONString()); + + gson.toJson(toJsonFromRequestObj(userInfo, scope, obj), out); + } catch (JsonSyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonIOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { - + gson.toJson(toJson(userInfo, scope), out); - + } - + } catch (IOException e) { - + logger.error("IOException in JSONUserInfoView.java: ", e); - + } } - + private JsonObject toJson(UserInfo ui, Set scope) { - + JsonObject obj = new JsonObject(); - + if (scope.contains("openid")) { obj.addProperty("sub", ui.getSub()); } - + if (scope.contains("profile")) { obj.addProperty("name", ui.getName()); obj.addProperty("preferred_username", ui.getPreferredUsername()); @@ -146,16 +149,16 @@ public class JSONUserInfoView extends AbstractView { obj.addProperty("updated_time", ui.getUpdatedTime()); obj.addProperty("birthdate", ui.getBirthdate()); } - + if (scope.contains("email")) { obj.addProperty("email", ui.getEmail()); obj.addProperty("email_verified", ui.getEmailVerified()); } - + if (scope.contains("phone")) { obj.addProperty("phone_number", ui.getPhoneNumber()); } - + if (scope.contains("address") && ui.getAddress() != null) { JsonObject addr = new JsonObject(); @@ -165,18 +168,18 @@ public class JSONUserInfoView extends AbstractView { addr.addProperty("region", ui.getAddress().getRegion()); addr.addProperty("postal_code", ui.getAddress().getPostalCode()); addr.addProperty("country", ui.getAddress().getCountry()); - + obj.add("address", addr); } - + return obj; } - + /** - * Build a JSON response according to the request object recieved. + * Build a JSON response according to the request object recieved. * - * Claims requested in requestObj.userinfo.claims are added to any + * Claims requested in requestObj.userinfo.claims are added to any * claims corresponding to requested scopes, if any. * * @param ui @@ -185,20 +188,20 @@ public class JSONUserInfoView extends AbstractView { * @return */ private JsonObject toJsonFromRequestObj(UserInfo ui, Set scope, JsonObject requestObj) { - + JsonObject obj = toJson(ui, scope); - + //Process list of requested claims out of the request object JsonElement userInfo = requestObj.get("userinfo"); if (userInfo == null || !userInfo.isJsonObject()) { return obj; } - + JsonElement claims = userInfo.getAsJsonObject().get("claims"); if (claims == null || !claims.isJsonObject()) { return obj; } - + //For each claim found, add it if not already present for (Entry i : claims.getAsJsonObject().entrySet()) { String claimName = i.getKey(); @@ -231,10 +234,10 @@ public class JSONUserInfoView extends AbstractView { } } } - - - + + + return obj; - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java index 14a957a45..45860826d 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java @@ -38,59 +38,62 @@ public class JsonApprovedSiteView extends AbstractView { private static Logger logger = LoggerFactory.getLogger(JsonApprovedSiteView.class); private Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - - return false; - } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }) - .registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer() { + .setExclusionStrategies(new ExclusionStrategy() { - @Override - public JsonElement serialize(OAuth2AccessTokenEntity src, - Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.getId()); + @Override + public boolean shouldSkipField(FieldAttributes f) { + + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; } - - }) - .serializeNulls() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .create(); + return false; + } + }) + .registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer() { + + @Override + public JsonElement serialize(OAuth2AccessTokenEntity src, + Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.getId()); + } + + }) + .serializeNulls() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); + + @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/json"); - + HttpStatus code = (HttpStatus) model.get("code"); if (code == null) { code = HttpStatus.OK; // default to 200 } - + response.setStatus(code.value()); - + try { - + Writer out = response.getWriter(); Object obj = model.get("entity"); - gson.toJson(obj, out); - + gson.toJson(obj, out); + } catch (IOException e) { - + //TODO: Error Handling logger.error("IOException in JsonEntityView.java: ", e); - + } - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonEntityView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonEntityView.java index ce98f233d..dc3edede5 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonEntityView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonEntityView.java @@ -32,50 +32,53 @@ public class JsonEntityView extends AbstractView { private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class); private Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - - return false; - } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }) - .serializeNulls() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .create(); + .setExclusionStrategies(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes f) { + + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; + } + return false; + } + + }) + .serializeNulls() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); + + @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/json"); - + HttpStatus code = (HttpStatus) model.get("code"); if (code == null) { code = HttpStatus.OK; // default to 200 } - + response.setStatus(code.value()); - + try { - + Writer out = response.getWriter(); Object obj = model.get("entity"); - gson.toJson(obj, out); - + gson.toJson(obj, out); + } catch (IOException e) { - + //TODO: Error Handling logger.error("IOException in JsonEntityView.java: ", e); - + } - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonErrorView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonErrorView.java index c610393f1..d0b58697e 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonErrorView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonErrorView.java @@ -30,53 +30,56 @@ public class JsonErrorView extends AbstractView { private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class); private Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - - return false; - } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }) - .serializeNulls() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .create(); + .setExclusionStrategies(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes f) { + + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; + } + return false; + } + + }) + .serializeNulls() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); + + @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/json"); - + HttpStatus code = (HttpStatus) model.get("code"); if (code == null) { code = HttpStatus.OK; // default to 200 } - + response.setStatus(code.value()); - + try { - + Writer out = response.getWriter(); - + String errorMessage = (String) model.get("errorMessage"); JsonObject obj = new JsonObject(); obj.addProperty("error_message", errorMessage); - gson.toJson(obj, out); - + gson.toJson(obj, out); + } catch (IOException e) { - + //TODO: Error Handling logger.error("IOException in JsonErrorView.java: ", e); - + } - } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/POCOUserInfoView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/POCOUserInfoView.java index ecac45333..07fcc39ea 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/POCOUserInfoView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/POCOUserInfoView.java @@ -39,73 +39,76 @@ import com.google.gson.JsonObject; @Component("pocoUserInfoView") public class POCOUserInfoView extends AbstractView { - + private static Logger logger = LoggerFactory.getLogger(POCOUserInfoView.class); - + /* (non-Javadoc) * @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ + @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { - + UserInfo userInfo = (UserInfo) model.get("userInfo"); Set scope = (Set) model.get("scope"); - + Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - public boolean shouldSkipField(FieldAttributes f) { - - return false; + .setExclusionStrategies(new ExclusionStrategy() { + + @Override + public boolean shouldSkipField(FieldAttributes f) { + + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; } - - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }).create(); + return false; + } + + }).create(); response.setContentType("application/json"); - + Writer out; - + try { - + out = response.getWriter(); gson.toJson(toPoco(userInfo, scope), out); - + } catch (IOException e) { - + logger.error("IOException in POCOUserInfoView.java: ", e); - + } - + } - + private JsonObject toPoco(UserInfo ui, Set scope) { JsonObject poco = new JsonObject(); - + // Envelope Info poco.addProperty("startIndex", 0); poco.addProperty("itemsPerPage", 1); poco.addProperty("totalResults", 1); - + // Build the entry for this userInfo, then add it to entries, then add it to poco JsonObject entry = new JsonObject(); - + if (scope.contains("openid")) { entry.addProperty("id", ui.getSub()); } - + if (scope.contains("profile")) { entry.addProperty("displayName", ui.getNickname()); - - if (ui.getFamilyName() != null - || ui.getGivenName() != null + + if (ui.getFamilyName() != null + || ui.getGivenName() != null || ui.getMiddleName() != null || ui.getName() != null) { JsonObject name = new JsonObject(); @@ -115,54 +118,54 @@ public class POCOUserInfoView extends AbstractView { name.addProperty("formatted", ui.getName()); entry.add("name", name); } - + entry.addProperty("gender", ui.getGender()); entry.addProperty("preferredUsername", ui.getPreferredUsername()); if (ui.getPicture() != null){ JsonObject photo = new JsonObject(); photo.addProperty("value", ui.getPicture()); - + JsonArray photoArray = new JsonArray(); photoArray.add(photo); entry.add("photos", photoArray); } - + if (ui.getWebsite() != null) { JsonObject website = new JsonObject(); website.addProperty("value", ui.getWebsite()); - + JsonArray websiteArray = new JsonArray(); websiteArray.add(website); entry.add("urls", websiteArray); } entry.addProperty("updated", ui.getUpdatedTime()); - + } - + if (scope.contains("email")) { if (ui.getEmail() != null) { JsonObject email = new JsonObject(); email.addProperty("value", ui.getEmail()); - + JsonArray emailArray = new JsonArray(); emailArray.add(email); entry.add("emails", emailArray); } } - + if (scope.contains("phone")) { if (ui.getPhoneNumber() != null){ JsonObject phone = new JsonObject(); phone.addProperty("value", ui.getPhoneNumber()); - + JsonArray phoneArray = new JsonArray(); phoneArray.add(phone); entry.add("phoneNumbers", phoneArray); } - + } - + if (scope.contains("address")) { if (ui.getAddress() != null) { JsonObject addr = new JsonObject(); @@ -172,13 +175,13 @@ public class POCOUserInfoView extends AbstractView { addr.addProperty("region", ui.getAddress().getRegion()); addr.addProperty("postalCode", ui.getAddress().getPostalCode()); addr.addProperty("country", ui.getAddress().getCountry()); - + JsonArray addrArray = new JsonArray(); addrArray.add(addr); entry.add("addresses", addrArray); } } - + JsonArray entryArray = new JsonArray(); entryArray.add(entry); poco.add("entry", entryArray); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/StatsSummary.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/StatsSummary.java index eba25548b..ecf5b8098 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/StatsSummary.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/StatsSummary.java @@ -28,42 +28,44 @@ public class StatsSummary extends AbstractView { @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { - Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { + Gson gson = new GsonBuilder() + .setExclusionStrategies(new ExclusionStrategy() { - public boolean shouldSkipField(FieldAttributes f) { + @Override + public boolean shouldSkipField(FieldAttributes f) { - return false; - } + return false; + } - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } + @Override + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; + } + return false; + } - }).create(); + }).create(); - response.setContentType("application/json"); + response.setContentType("application/json"); - try { - - Writer out = response.getWriter(); - Object obj = model.get("entity"); - if (obj == null) { - obj = model; - } + try { - gson.toJson(obj, out); - - } catch (IOException e) { - - logger.error("IOException in JSONClientView.java: ", e); - - } + Writer out = response.getWriter(); + Object obj = model.get("entity"); + if (obj == null) { + obj = model; + } + + gson.toJson(obj, out); + + } catch (IOException e) { + + logger.error("IOException in JSONClientView.java: ", e); + + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java index 7305536c0..face58ae8 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java @@ -31,10 +31,10 @@ public class ApprovedSiteAPI { @Autowired private ApprovedSiteService approvedSiteService; - + @Autowired OAuth2TokenEntityService tokenServices; - + private static Logger logger = LoggerFactory.getLogger(ApprovedSiteAPI.class); /** @@ -44,14 +44,14 @@ public class ApprovedSiteAPI { */ @RequestMapping(method = RequestMethod.GET, produces = "application/json") public String getAllApprovedSites(ModelMap m, Principal p) { - + Collection all = approvedSiteService.getByUserId(p.getName()); - + m.put("entity", all); - + return "jsonApprovedSiteView"; } - + /** * Delete an approved site * @@ -59,26 +59,26 @@ public class ApprovedSiteAPI { @RequestMapping(value="/{id}", method = RequestMethod.DELETE) public String deleteApprovedSite(@PathVariable("id") Long id, ModelMap m, Principal p) { ApprovedSite approvedSite = approvedSiteService.getById(id); - + if (approvedSite == null) { logger.error("deleteApprovedSite failed; no approved site found for id: " + id); m.put("code", HttpStatus.NOT_FOUND); m.put("errorMessage", "Could not delete approved site. The requested approved site with id: " + id + " could not be found."); return "jsonErrorView"; } else if (!approvedSite.getUserId().equals(p.getName())) { - logger.error("deleteApprovedSite failed; principal " + logger.error("deleteApprovedSite failed; principal " + p.getName() + " does not own approved site" + id); m.put("code", HttpStatus.FORBIDDEN); m.put("errorMessage", "You do not have permission to delete this approved site. The approved site decision will not be deleted."); return "jsonErrorView"; } else { m.put("code", HttpStatus.OK); - approvedSiteService.remove(approvedSite); - } - + approvedSiteService.remove(approvedSite); + } + return "httpCodeView"; } - + /** * Get a single approved site */ @@ -91,7 +91,7 @@ public class ApprovedSiteAPI { m.put("errorMessage", "The requested approved site with id: " + id + " could not be found."); return "jsonErrorView"; } else if (!approvedSite.getUserId().equals(p.getName())) { - logger.error("getApprovedSite failed; principal " + logger.error("getApprovedSite failed; principal " + p.getName() + " does not own approved site" + id); m.put("code", HttpStatus.FORBIDDEN); m.put("errorMessage", "You do not have permission to view this approved site."); @@ -100,6 +100,6 @@ public class ApprovedSiteAPI { m.put("entity", approvedSite); return "jsonApprovedSiteView"; } - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/BlacklistAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/BlacklistAPI.java index f535c6e14..2b522885f 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/BlacklistAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/BlacklistAPI.java @@ -36,12 +36,12 @@ public class BlacklistAPI { @Autowired private BlacklistedSiteService blacklistService; - + private static Logger logger = LoggerFactory.getLogger(BlacklistAPI.class); - + private Gson gson = new Gson(); private JsonParser parser = new JsonParser(); - + /** * Get a list of all blacklisted sites * @param m @@ -49,14 +49,14 @@ public class BlacklistAPI { */ @RequestMapping(method = RequestMethod.GET, produces = "application/json") public String getAllBlacklistedSites(ModelMap m) { - + Collection all = blacklistService.getAll(); - + m.put("entity", all); - + return "jsonEntityView"; } - + /** * Create a new blacklisted site * @param jsonString @@ -66,19 +66,19 @@ public class BlacklistAPI { */ @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public String addNewBlacklistedSite(@RequestBody String jsonString, ModelMap m, Principal p) { - - JsonObject json; - + + JsonObject json; + BlacklistedSite blacklist = null; - + try { - + json = parser.parse(jsonString).getAsJsonObject(); blacklist = gson.fromJson(json, BlacklistedSite.class); BlacklistedSite newBlacklist = blacklistService.saveNew(blacklist); m.put("entity", newBlacklist); - - } + + } catch (JsonSyntaxException e) { logger.error("addNewBlacklistedSite failed due to JsonSyntaxException: " , e); m.put("code", HttpStatus.BAD_REQUEST); @@ -90,27 +90,27 @@ public class BlacklistAPI { m.put("errorMessage", "Could not save new blacklisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); return "jsonErrorView"; } - + return "jsonEntityView"; - + } - + /** * Update an existing blacklisted site */ @RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json") public String updateBlacklistedSite(@PathVariable("id") Long id, @RequestBody String jsonString, ModelMap m, Principal p) { - - JsonObject json; - - BlacklistedSite blacklist = null; - + + JsonObject json; + + BlacklistedSite blacklist = null; + try { - + json = parser.parse(jsonString).getAsJsonObject(); blacklist = gson.fromJson(json, BlacklistedSite.class); - - } + + } catch (JsonSyntaxException e) { logger.error("updateBlacklistedSite failed due to JsonSyntaxException: " , e); m.put("code", HttpStatus.BAD_REQUEST); @@ -122,25 +122,25 @@ public class BlacklistAPI { m.put("errorMessage", "Could not update blacklisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); return "jsonErrorView"; } - - + + BlacklistedSite oldBlacklist = blacklistService.getById(id); - + if (oldBlacklist == null) { logger.error("updateBlacklistedSite failed; blacklist with id " + id + " could not be found"); m.put("code", HttpStatus.NOT_FOUND); m.put("errorMessage", "Could not update blacklisted site. The requested blacklist with id " + id + "could not be found."); return "jsonErrorView"; } else { - + BlacklistedSite newBlacklist = blacklistService.update(oldBlacklist, blacklist); - + m.put("entity", newBlacklist); - + return "jsonEntityView"; } } - + /** * Delete a blacklisted site * @@ -148,7 +148,7 @@ public class BlacklistAPI { @RequestMapping(value="/{id}", method = RequestMethod.DELETE) public String deleteBlacklistedSite(@PathVariable("id") Long id, ModelMap m) { BlacklistedSite blacklist = blacklistService.getById(id); - + if (blacklist == null) { logger.error("deleteBlacklistedSite failed; blacklist with id " + id + " could not be found"); m.put("errorMessage", "Could not delete bladklist. The requested bladklist with id " + id + " could not be found."); @@ -156,11 +156,11 @@ public class BlacklistAPI { } else { m.put("code", HttpStatus.OK); blacklistService.remove(blacklist); - } - + } + return "httpCodeView"; } - + /** * Get a single blacklisted site */ @@ -173,11 +173,11 @@ public class BlacklistAPI { m.put("errorMessage", "Could not delete bladklist. The requested bladklist with id " + id + " could not be found."); return "jsonErrorView"; } else { - + m.put("entity", blacklist); - + return "jsonEntityView"; } - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java index 09b73e789..3876b5ae3 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java @@ -58,111 +58,111 @@ import com.google.gson.JsonSyntaxException; @PreAuthorize("hasRole('ROLE_USER')") public class ClientAPI { - @Autowired - private ClientDetailsEntityService clientService; + @Autowired + private ClientDetailsEntityService clientService; private JsonParser parser = new JsonParser(); private Gson gson = new GsonBuilder() - .serializeNulls() - .registerTypeAdapter(JWSAlgorithmEmbed.class, new JsonDeserializer() { - @Override - public JWSAlgorithmEmbed deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - if (json.isJsonPrimitive()) { - return JWSAlgorithmEmbed.getForAlgorithmName(json.getAsString()); - } else { - return null; - } - } - }) - .registerTypeAdapter(JWEAlgorithmEmbed.class, new JsonDeserializer() { - @Override - public JWEAlgorithmEmbed deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - if (json.isJsonPrimitive()) { - return JWEAlgorithmEmbed.getForAlgorithmName(json.getAsString()); - } else { - return null; - } - } - }) - .registerTypeAdapter(JWEEncryptionMethodEmbed.class, new JsonDeserializer() { - @Override - public JWEEncryptionMethodEmbed deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - if (json.isJsonPrimitive()) { - return JWEEncryptionMethodEmbed.getForAlgorithmName(json.getAsString()); - } else { - return null; - } - } - }) - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .create(); - + .serializeNulls() + .registerTypeAdapter(JWSAlgorithmEmbed.class, new JsonDeserializer() { + @Override + public JWSAlgorithmEmbed deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json.isJsonPrimitive()) { + return JWSAlgorithmEmbed.getForAlgorithmName(json.getAsString()); + } else { + return null; + } + } + }) + .registerTypeAdapter(JWEAlgorithmEmbed.class, new JsonDeserializer() { + @Override + public JWEAlgorithmEmbed deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json.isJsonPrimitive()) { + return JWEAlgorithmEmbed.getForAlgorithmName(json.getAsString()); + } else { + return null; + } + } + }) + .registerTypeAdapter(JWEEncryptionMethodEmbed.class, new JsonDeserializer() { + @Override + public JWEEncryptionMethodEmbed deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json.isJsonPrimitive()) { + return JWEEncryptionMethodEmbed.getForAlgorithmName(json.getAsString()); + } else { + return null; + } + } + }) + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); + private static Logger logger = LoggerFactory.getLogger(ClientAPI.class); - /** - * Get a list of all clients - * @param modelAndView - * @return - */ - @RequestMapping(method = RequestMethod.GET, produces = "application/json") - public String apiGetAllClients(Model model, Authentication auth) { + /** + * Get a list of all clients + * @param modelAndView + * @return + */ + @RequestMapping(method = RequestMethod.GET, produces = "application/json") + public String apiGetAllClients(Model model, Authentication auth) { - Collection clients = clientService.getAllClients(); - model.addAttribute("entity", clients); + Collection clients = clientService.getAllClients(); + model.addAttribute("entity", clients); if (isAdmin(auth)) { return "clientEntityViewAdmins"; } else { return "clientEntityViewUsers"; } - } + } - /** - * Create a new client - * @param json - * @param m - * @param principal - * @return - */ - @PreAuthorize("hasRole('ROLE_ADMIN')") - @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") - public String apiAddClient(@RequestBody String jsonString, Model m, Authentication auth) { + /** + * Create a new client + * @param json + * @param m + * @param principal + * @return + */ + @PreAuthorize("hasRole('ROLE_ADMIN')") + @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") + public String apiAddClient(@RequestBody String jsonString, Model m, Authentication auth) { - JsonObject json = null; - ClientDetailsEntity client = null; - - try { - json = parser.parse(jsonString).getAsJsonObject(); - client = gson.fromJson(json, ClientDetailsEntity.class); - } - catch (JsonSyntaxException e) { - logger.error("apiAddClient failed due to JsonSyntaxException: " , e); - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Could not save new client. The server encountered a JSON syntax exception. Contact a system administrator for assistance."); + JsonObject json = null; + ClientDetailsEntity client = null; + + try { + json = parser.parse(jsonString).getAsJsonObject(); + client = gson.fromJson(json, ClientDetailsEntity.class); + } + catch (JsonSyntaxException e) { + logger.error("apiAddClient failed due to JsonSyntaxException: " , e); + m.addAttribute("code", HttpStatus.BAD_REQUEST); + m.addAttribute("errorMessage", "Could not save new client. The server encountered a JSON syntax exception. Contact a system administrator for assistance."); return "jsonErrorView"; - } catch (IllegalStateException e) { - logger.error("apiAddClient failed due to IllegalStateException: " , e); - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Could not save new client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); + } catch (IllegalStateException e) { + logger.error("apiAddClient failed due to IllegalStateException: " , e); + m.addAttribute("code", HttpStatus.BAD_REQUEST); + m.addAttribute("errorMessage", "Could not save new client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); return "jsonErrorView"; } - - // if they leave the client secret empty, force it to be generated - if (Strings.isNullOrEmpty(client.getClientId())) { - client = clientService.generateClientId(client); - } - - // if they've asked for us to generate a client secret, do so here - if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()) { - client = clientService.generateClientSecret(client); - } - - // set owners as current logged in user - //client.setOwner(principal.getName()); - //TODO: owner has been replaced by a list of contacts, which should be styled as email addresses. - client.setDynamicallyRegistered(false); - - ClientDetailsEntity newClient = clientService.saveNewClient(client); + + // if they leave the client secret empty, force it to be generated + if (Strings.isNullOrEmpty(client.getClientId())) { + client = clientService.generateClientId(client); + } + + // if they've asked for us to generate a client secret, do so here + if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()) { + client = clientService.generateClientSecret(client); + } + + // set owners as current logged in user + //client.setOwner(principal.getName()); + //TODO: owner has been replaced by a list of contacts, which should be styled as email addresses. + client.setDynamicallyRegistered(false); + + ClientDetailsEntity newClient = clientService.saveNewClient(client); m.addAttribute("entity", newClient); if (isAdmin(auth)) { @@ -170,64 +170,64 @@ public class ClientAPI { } else { return "clientEntityViewUsers"; } - } + } - /** - * Update an existing client - * @param id - * @param jsonString - * @param m - * @param principal - * @return - */ - @PreAuthorize("hasRole('ROLE_ADMIN')") - @RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json") - public String apiUpdateClient(@PathVariable("id") Long id, @RequestBody String jsonString, Model m, Authentication auth) { - - JsonObject json = null; - ClientDetailsEntity client = null; - - try { - // parse the client passed in (from JSON) and fetch the old client from the store - json = parser.parse(jsonString).getAsJsonObject(); - client = gson.fromJson(json, ClientDetailsEntity.class); - } - catch (JsonSyntaxException e) { - logger.error("apiUpdateClient failed due to JsonSyntaxException: " , e); - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Could not update client. The server encountered a JSON syntax exception. Contact a system administrator for assistance."); + /** + * Update an existing client + * @param id + * @param jsonString + * @param m + * @param principal + * @return + */ + @PreAuthorize("hasRole('ROLE_ADMIN')") + @RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json") + public String apiUpdateClient(@PathVariable("id") Long id, @RequestBody String jsonString, Model m, Authentication auth) { + + JsonObject json = null; + ClientDetailsEntity client = null; + + try { + // parse the client passed in (from JSON) and fetch the old client from the store + json = parser.parse(jsonString).getAsJsonObject(); + client = gson.fromJson(json, ClientDetailsEntity.class); + } + catch (JsonSyntaxException e) { + logger.error("apiUpdateClient failed due to JsonSyntaxException: " , e); + m.addAttribute("code", HttpStatus.BAD_REQUEST); + m.addAttribute("errorMessage", "Could not update client. The server encountered a JSON syntax exception. Contact a system administrator for assistance."); return "jsonErrorView"; - } catch (IllegalStateException e) { - logger.error("apiUpdateClient failed due to IllegalStateException: " , e); - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Could not update client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); + } catch (IllegalStateException e) { + logger.error("apiUpdateClient failed due to IllegalStateException: " , e); + m.addAttribute("code", HttpStatus.BAD_REQUEST); + m.addAttribute("errorMessage", "Could not update client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); return "jsonErrorView"; } - ClientDetailsEntity oldClient = clientService.getClientById(id); - - if (oldClient == null) { - logger.error("apiUpdateClient failed; client with id " + id + " could not be found."); - m.addAttribute("code", HttpStatus.NOT_FOUND); - m.addAttribute("errorMessage", "Could not update client. The requested client with id " + id + "could not be found."); + ClientDetailsEntity oldClient = clientService.getClientById(id); + + if (oldClient == null) { + logger.error("apiUpdateClient failed; client with id " + id + " could not be found."); + m.addAttribute("code", HttpStatus.NOT_FOUND); + m.addAttribute("errorMessage", "Could not update client. The requested client with id " + id + "could not be found."); return "jsonErrorView"; - } - - // if they leave the client secret empty, force it to be generated - if (Strings.isNullOrEmpty(client.getClientId())) { - client = clientService.generateClientId(client); - } - - // if they've asked for us to generate a client secret, do so here - if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()) { - client = clientService.generateClientSecret(client); - } - - // set owners as current logged in user - // client.setOwner(principal.getName()); - //TODO: owner has been replaced by a list of contacts, which should be styled as email addresses. - - ClientDetailsEntity newClient = clientService.updateClient(oldClient, client); + } + + // if they leave the client secret empty, force it to be generated + if (Strings.isNullOrEmpty(client.getClientId())) { + client = clientService.generateClientId(client); + } + + // if they've asked for us to generate a client secret, do so here + if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()) { + client = clientService.generateClientSecret(client); + } + + // set owners as current logged in user + // client.setOwner(principal.getName()); + //TODO: owner has been replaced by a list of contacts, which should be styled as email addresses. + + ClientDetailsEntity newClient = clientService.updateClient(oldClient, client); m.addAttribute("entity", newClient); if (isAdmin(auth)) { @@ -235,20 +235,20 @@ public class ClientAPI { } else { return "clientEntityViewUsers"; } - } + } - /** - * Delete a client - * @param id - * @param modelAndView - * @return - */ - @PreAuthorize("hasRole('ROLE_ADMIN')") - @RequestMapping(value="/{id}", method=RequestMethod.DELETE) - public String apiDeleteClient(@PathVariable("id") Long id, ModelAndView modelAndView) { + /** + * Delete a client + * @param id + * @param modelAndView + * @return + */ + @PreAuthorize("hasRole('ROLE_ADMIN')") + @RequestMapping(value="/{id}", method=RequestMethod.DELETE) + public String apiDeleteClient(@PathVariable("id") Long id, ModelAndView modelAndView) { + + ClientDetailsEntity client = clientService.getClientById(id); - ClientDetailsEntity client = clientService.getClientById(id); - if (client == null) { logger.error("apiDeleteClient failed; client with id " + id + " could not be found."); modelAndView.getModelMap().put("code", HttpStatus.NOT_FOUND); @@ -257,50 +257,50 @@ public class ClientAPI { } else { modelAndView.getModelMap().put("code", HttpStatus.OK); clientService.deleteClient(client); - } - + } + return "httpCodeView"; - } + } - /** - * Get an individual client - * @param id - * @param modelAndView - * @return - */ - @RequestMapping(value="/{id}", method=RequestMethod.GET, produces = "application/json") - public String apiShowClient(@PathVariable("id") Long id, Model model, Authentication auth) { + /** + * Get an individual client + * @param id + * @param modelAndView + * @return + */ + @RequestMapping(value="/{id}", method=RequestMethod.GET, produces = "application/json") + public String apiShowClient(@PathVariable("id") Long id, Model model, Authentication auth) { - ClientDetailsEntity client = clientService.getClientById(id); - - if (client == null) { - logger.error("apiShowClient failed; client with id " + id + " could not be found."); - model.addAttribute("code", HttpStatus.NOT_FOUND); - model.addAttribute("errorMessage", "The requested client with id " + id + "could not be found."); + ClientDetailsEntity client = clientService.getClientById(id); + + if (client == null) { + logger.error("apiShowClient failed; client with id " + id + " could not be found."); + model.addAttribute("code", HttpStatus.NOT_FOUND); + model.addAttribute("errorMessage", "The requested client with id " + id + "could not be found."); return "jsonErrorView"; - } + } - model.addAttribute("entity", client); + model.addAttribute("entity", client); - if (isAdmin(auth)) { + if (isAdmin(auth)) { return "clientEntityViewAdmins"; } else { return "clientEntityViewUsers"; } - } - - /** - * Check to see if the given auth object has ROLE_ADMIN assigned to it or not - * @param auth - * @return - */ - private boolean isAdmin(Authentication auth) { - for (GrantedAuthority grantedAuthority : auth.getAuthorities()) { - if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) { - return true; - } - } - return false; - } + } + + /** + * Check to see if the given auth object has ROLE_ADMIN assigned to it or not + * @param auth + * @return + */ + private boolean isAdmin(Authentication auth) { + for (GrantedAuthority grantedAuthority : auth.getAuthorities()) { + if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) { + return true; + } + } + return false; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java index a1b9e9bd1..2da44b336 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java @@ -52,20 +52,20 @@ public class ClientDynamicRegistrationEndpoint { @Autowired private ClientDetailsEntityService clientService; - + @Autowired private OAuth2TokenEntityService tokenService; @Autowired private SystemScopeService scopeService; - + @Autowired private OAuth2RequestFactory oAuth2RequestFactory; - + private static Logger logger = LoggerFactory.getLogger(ClientDynamicRegistrationEndpoint.class); private JsonParser parser = new JsonParser(); private Gson gson = new Gson(); - + /** * Create a new Client, issue a client ID, and create a registration access token. * @param jsonString @@ -75,20 +75,20 @@ public class ClientDynamicRegistrationEndpoint { */ @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public String registerNewClient(@RequestBody String jsonString, Model m) { - + ClientDetailsEntity newClient = parse(jsonString); - + if (newClient != null) { // it parsed! - + // // Now do some post-processing consistency checks on it // - + // clear out any spurious id/secret (clients don't get to pick) newClient.setClientId(null); newClient.setClientSecret(null); - + // set of scopes that are OK for clients to dynamically register for Set dynScopes = scopeService.getDynReg(); @@ -104,32 +104,32 @@ public class ClientDynamicRegistrationEndpoint { Set allowedScopes = Sets.intersection(dynScopes, requestedScopes); newClient.setScope(scopeService.toStrings(allowedScopes)); - + // set default grant types if needed - if (newClient.getGrantTypes() == null || newClient.getGrantTypes().isEmpty()) { + if (newClient.getGrantTypes() == null || newClient.getGrantTypes().isEmpty()) { newClient.setGrantTypes(Sets.newHashSet("authorization_code", "refresh_token")); // allow authorization code and refresh token grant types by default } - + // set default response types if needed // TODO: these aren't checked by SECOAUTH // TODO: the consistency between the response_type and grant_type needs to be checked by the client service, most likely if (newClient.getResponseTypes() == null || newClient.getResponseTypes().isEmpty()) { newClient.setResponseTypes(Sets.newHashSet("code")); // default to allowing only the auth code flow } - + if (newClient.getTokenEndpointAuthMethod() == null) { newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC); } - + if (newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_BASIC || newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_JWT || newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_POST) { - + // we need to generate a secret newClient = clientService.generateClientSecret(newClient); } - + // set some defaults for token timeouts newClient.setAccessTokenValiditySeconds((int)TimeUnit.HOURS.toSeconds(1)); // access tokens good for 1hr newClient.setIdTokenValiditySeconds((int)TimeUnit.MINUTES.toSeconds(10)); // id tokens good for 10min @@ -137,27 +137,27 @@ public class ClientDynamicRegistrationEndpoint { // this client has been dynamically registered (obviously) newClient.setDynamicallyRegistered(true); - + // now save it ClientDetailsEntity savedClient = clientService.saveNewClient(newClient); - + // generate the registration access token OAuth2AccessTokenEntity token = createRegistrationAccessToken(savedClient); - + // send it all out to the view m.addAttribute("client", savedClient); m.addAttribute("code", HttpStatus.CREATED); // http 201 m.addAttribute("token", token); - + return "clientInformationResponseView"; } else { // didn't parse, this is a bad request logger.error("registerNewClient failed; submitted JSON is malformed"); m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400 - + return "httpCodeView"; } - + } /** @@ -170,32 +170,32 @@ public class ClientDynamicRegistrationEndpoint { @PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" + OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE + "')") @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json") public String readClientConfiguration(@PathVariable("id") String clientId, Model m, OAuth2Authentication auth) { - + ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - + if (client != null && client.getClientId().equals(auth.getOAuth2Request().getClientId())) { - + // we return the token that we got in OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails(); OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue()); - + // send it all out to the view m.addAttribute("client", client); m.addAttribute("code", HttpStatus.OK); // http 200 m.addAttribute("token", token); - + return "clientInformationResponseView"; } else { // client mismatch - logger.error("readClientConfiguration failed, client ID mismatch: " + logger.error("readClientConfiguration failed, client ID mismatch: " + clientId + " and " + auth.getOAuth2Request().getClientId() + " do not match."); m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403 - + return "httpCodeView"; } } - + /** * Update the metainformation for a given client. * @param clientId @@ -208,10 +208,10 @@ public class ClientDynamicRegistrationEndpoint { @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json") public String updateClient(@PathVariable("id") String clientId, @RequestBody String jsonString, Model m, OAuth2Authentication auth) { - + ClientDetailsEntity newClient = parse(jsonString); ClientDetailsEntity oldClient = clientService.loadClientByClientId(clientId); - + if (newClient != null && oldClient != null // we have an existing client and the new one parsed && oldClient.getClientId().equals(auth.getOAuth2Request().getClientId()) // the client passed in the URI matches the one in the auth && oldClient.getClientId().equals(newClient.getClientId()) // the client passed in the body matches the one in the URI @@ -219,7 +219,7 @@ public class ClientDynamicRegistrationEndpoint { // a client can't ask to update its own client secret to any particular value newClient.setClientSecret(oldClient.getClientSecret()); - + // we need to copy over all of the local and SECOAUTH fields newClient.setAccessTokenValiditySeconds(oldClient.getAccessTokenValiditySeconds()); newClient.setIdTokenValiditySeconds(oldClient.getIdTokenValiditySeconds()); @@ -230,7 +230,7 @@ public class ClientDynamicRegistrationEndpoint { newClient.setClientDescription(oldClient.getClientDescription()); newClient.setCreatedAt(oldClient.getCreatedAt()); newClient.setReuseRefreshToken(oldClient.isReuseRefreshToken()); - + // set of scopes that are OK for clients to dynamically register for Set dynScopes = scopeService.getDynReg(); @@ -242,27 +242,27 @@ public class ClientDynamicRegistrationEndpoint { // make sure that the client doesn't ask for scopes it can't have newClient.setScope(scopeService.toStrings(allowedScopes)); - + // save the client ClientDetailsEntity savedClient = clientService.updateClient(oldClient, newClient); - + // we return the token that we got in // TODO: rotate this after some set amount of time OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails(); OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue()); - + // send it all out to the view m.addAttribute("client", savedClient); m.addAttribute("code", HttpStatus.OK); // http 200 m.addAttribute("token", token); - + return "clientInformationResponseView"; } else { // client mismatch - logger.error("readClientConfiguration failed, client ID mismatch: " + logger.error("readClientConfiguration failed, client ID mismatch: " + clientId + " and " + auth.getOAuth2Request().getClientId() + " do not match."); m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403 - + return "httpCodeView"; } } @@ -277,36 +277,36 @@ public class ClientDynamicRegistrationEndpoint { @PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" + OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE + "')") @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = "application/json") public String deleteClient(@PathVariable("id") String clientId, Model m, OAuth2Authentication auth) { - + ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - + if (client != null && client.getClientId().equals(auth.getOAuth2Request().getClientId())) { clientService.deleteClient(client); - + // we return the token that we got in OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails(); OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue()); - + // send it all out to the view m.addAttribute("client", client); m.addAttribute("code", HttpStatus.OK); // http 200 m.addAttribute("token", token); - + return "clientInformationResponseView"; } else { // client mismatch - logger.error("readClientConfiguration failed, client ID mismatch: " + logger.error("readClientConfiguration failed, client ID mismatch: " + clientId + " and " + auth.getOAuth2Request().getClientId() + " do not match."); m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403 - + return "httpCodeView"; } } - - - - + + + + /** * * Create an unbound ClientDetailsEntity from the given JSON string. @@ -314,19 +314,19 @@ public class ClientDynamicRegistrationEndpoint { * @param jsonString * @return the entity if successful, null otherwise */ - private ClientDetailsEntity parse(String jsonString) { + private ClientDetailsEntity parse(String jsonString) { JsonElement jsonEl = parser.parse(jsonString); if (jsonEl.isJsonObject()) { JsonObject o = jsonEl.getAsJsonObject(); ClientDetailsEntity c = new ClientDetailsEntity(); - + // TODO: make these field names into constants // these two fields should only be sent in the update request, and MUST match existing values c.setClientId(getAsString(o, "client_id")); c.setClientSecret(getAsString(o, "client_secret")); - + // OAuth DynReg c.setRedirectUris(getAsStringSet(o, "redirect_uris")); c.setClientName(getAsString(o, "client_name")); @@ -334,148 +334,148 @@ public class ClientDynamicRegistrationEndpoint { c.setLogoUri(getAsString(o, "logo_uri")); c.setContacts(getAsStringSet(o, "contacts")); c.setTosUri(getAsString(o, "tos_uri")); - + String authMethod = getAsString(o, "token_endpoint_auth_method"); if (authMethod != null) { c.setTokenEndpointAuthMethod(AuthMethod.getByValue(authMethod)); } - + // scope is a space-separated string String scope = getAsString(o, "scope"); if (scope != null) { c.setScope(Sets.newHashSet(Splitter.on(" ").split(scope))); } - + c.setGrantTypes(getAsStringSet(o, "grant_types")); c.setPolicyUri(getAsString(o, "policy_uri")); c.setJwksUri(getAsString(o, "jwks_uri")); - - + + // OIDC Additions String appType = getAsString(o, "application_type"); if (appType != null) { c.setApplicationType(AppType.getByValue(appType)); } - + c.setSectorIdentifierUri(getAsString(o, "sector_identifier_uri")); - + String subjectType = getAsString(o, "subject_type"); if (subjectType != null) { c.setSubjectType(SubjectType.getByValue(subjectType)); } - + c.setRequestObjectSigningAlg(getAsJwsAlgorithm(o, "request_object_signing_alg")); - + c.setUserInfoSignedResponseAlg(getAsJwsAlgorithm(o, "userinfo_signed_response_alg")); c.setUserInfoEncryptedResponseAlg(getAsJweAlgorithm(o, "userinfo_encrypted_response_alg")); c.setUserInfoEncryptedResponseEnc(getAsJweEncryptionMethod(o, "userinfo_encrypted_response_enc")); - + c.setIdTokenSignedResponseAlg(getAsJwsAlgorithm(o, "id_token_signed_response_alg")); c.setIdTokenEncryptedResponseAlg(getAsJweAlgorithm(o, "id_token_encrypted_response_alg")); c.setIdTokenEncryptedResponseEnc(getAsJweEncryptionMethod(o, "id_token_encrypted_response_enc")); - + if (o.has("default_max_age")) { if (o.get("default_max_age").isJsonPrimitive()) { c.setDefaultMaxAge(o.get("default_max_age").getAsInt()); } } - + if (o.has("require_auth_time")) { if (o.get("require_auth_time").isJsonPrimitive()) { c.setRequireAuthTime(o.get("require_auth_time").getAsBoolean()); } } - + c.setDefaultACRvalues(getAsStringSet(o, "default_acr_values")); c.setInitiateLoginUri(getAsString(o, "initiate_login_uri")); c.setPostLogoutRedirectUri(getAsString(o, "post_logout_redirect_uri")); c.setRequestUris(getAsStringSet(o, "request_uris")); - + return c; } else { - return null; + return null; } - } + } /** * Gets the value of the given given member as a set of strings, null if it doesn't exist */ - private Set getAsStringSet(JsonObject o, String member) throws JsonSyntaxException { - if (o.has(member)) { - return gson.fromJson(o.get(member), new TypeToken>(){}.getType()); - } else { - return null; - } - } - - /** - * Gets the value of the given member as a string, null if it doesn't exist - */ - private String getAsString(JsonObject o, String member) { - if (o.has(member)) { - JsonElement e = o.get(member); - if (e != null && e.isJsonPrimitive()) { - return e.getAsString(); - } else { - return null; - } - } else { - return null; - } - } - - /** - * Gets the value of the given member as a JWS Algorithm, null if it doesn't exist - */ - private JWSAlgorithmEmbed getAsJwsAlgorithm(JsonObject o, String member) { - String s = getAsString(o, member); - if (s != null) { - return JWSAlgorithmEmbed.getForAlgorithmName(s); - } else { - return null; - } - } + private Set getAsStringSet(JsonObject o, String member) throws JsonSyntaxException { + if (o.has(member)) { + return gson.fromJson(o.get(member), new TypeToken>(){}.getType()); + } else { + return null; + } + } - /** - * Gets the value of the given member as a JWE Algorithm, null if it doesn't exist - */ - private JWEAlgorithmEmbed getAsJweAlgorithm(JsonObject o, String member) { - String s = getAsString(o, member); - if (s != null) { - return JWEAlgorithmEmbed.getForAlgorithmName(s); - } else { - return null; - } - } - - - /** - * Gets the value of the given member as a JWE Encryption Method, null if it doesn't exist - */ - private JWEEncryptionMethodEmbed getAsJweEncryptionMethod(JsonObject o, String member) { - String s = getAsString(o, member); - if (s != null) { - return JWEEncryptionMethodEmbed.getForAlgorithmName(s); - } else { - return null; - } - } /** - * @param client - * @return - * @throws AuthenticationException - */ - private OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) throws AuthenticationException { - - Map authorizationParameters = Maps.newHashMap(); - authorizationParameters.put("client_id", client.getClientId()); - authorizationParameters.put("scope", OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE); - OAuth2Request storedRequest = new OAuth2Request(authorizationParameters, client.getClientId(), - Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true, - Sets.newHashSet(OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE), null, null, null); + * Gets the value of the given member as a string, null if it doesn't exist + */ + private String getAsString(JsonObject o, String member) { + if (o.has(member)) { + JsonElement e = o.get(member); + if (e != null && e.isJsonPrimitive()) { + return e.getAsString(); + } else { + return null; + } + } else { + return null; + } + } + + /** + * Gets the value of the given member as a JWS Algorithm, null if it doesn't exist + */ + private JWSAlgorithmEmbed getAsJwsAlgorithm(JsonObject o, String member) { + String s = getAsString(o, member); + if (s != null) { + return JWSAlgorithmEmbed.getForAlgorithmName(s); + } else { + return null; + } + } + + /** + * Gets the value of the given member as a JWE Algorithm, null if it doesn't exist + */ + private JWEAlgorithmEmbed getAsJweAlgorithm(JsonObject o, String member) { + String s = getAsString(o, member); + if (s != null) { + return JWEAlgorithmEmbed.getForAlgorithmName(s); + } else { + return null; + } + } + + + /** + * Gets the value of the given member as a JWE Encryption Method, null if it doesn't exist + */ + private JWEEncryptionMethodEmbed getAsJweEncryptionMethod(JsonObject o, String member) { + String s = getAsString(o, member); + if (s != null) { + return JWEEncryptionMethodEmbed.getForAlgorithmName(s); + } else { + return null; + } + } + /** + * @param client + * @return + * @throws AuthenticationException + */ + private OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) throws AuthenticationException { + + Map authorizationParameters = Maps.newHashMap(); + authorizationParameters.put("client_id", client.getClientId()); + authorizationParameters.put("scope", OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE); + OAuth2Request storedRequest = new OAuth2Request(authorizationParameters, client.getClientId(), + Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true, + Sets.newHashSet(OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE), null, null, null); OAuth2Authentication authentication = new OAuth2Authentication(storedRequest, null); OAuth2AccessTokenEntity registrationAccessToken = (OAuth2AccessTokenEntity) tokenService.createAccessToken(authentication); - return registrationAccessToken; - } - + return registrationAccessToken; + } + } \ No newline at end of file diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/JsonWebKeyEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/JsonWebKeyEndpoint.java index bfe0b5979..0f80816e1 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/JsonWebKeyEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/JsonWebKeyEndpoint.java @@ -30,32 +30,32 @@ public class JsonWebKeyEndpoint { @Autowired private JwtSigningAndValidationService jwtService; - + @RequestMapping(value = "/jwk", produces = "application/json") public String getJwk(Model m) { - + // map from key id to key Map keys = jwtService.getAllPublicKeys(); - + // TODO: check if keys are empty, return a 404 here or just an empty list? - + m.addAttribute("keys", keys); - + return "jwkKeyList"; } - - /** - * @return the jwtService - */ - public JwtSigningAndValidationService getJwtService() { - return jwtService; - } /** - * @param jwtService the jwtService to set - */ - public void setJwtService(JwtSigningAndValidationService jwtService) { - this.jwtService = jwtService; - } - + * @return the jwtService + */ + public JwtSigningAndValidationService getJwtService() { + return jwtService; + } + + /** + * @param jwtService the jwtService to set + */ + public void setJwtService(JwtSigningAndValidationService jwtService) { + this.jwtService = jwtService; + } + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ManagerController.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ManagerController.java index c30f6a062..ef1732ccb 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ManagerController.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ManagerController.java @@ -17,7 +17,6 @@ package org.mitre.openid.connect.web; import java.util.Map; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; import org.mitre.openid.connect.service.StatsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; @@ -34,42 +33,42 @@ public class ManagerController { @Autowired private StatsService statsService; - - @RequestMapping({"", "home", "index"}) - public String showHomePage(ModelMap m) { - - Map summary = statsService.calculateSummaryStats(); - - m.put("statsSummary", summary); - return "home"; - } - - @RequestMapping({"about", "about/"}) - public String showAboutPage(ModelMap m) { - - return "about"; - } - - @RequestMapping({"stats", "stats/"}) - public String showStatsPage(ModelMap m) { - - Map summary = statsService.calculateSummaryStats(); - - m.put("statsSummary", summary); - return "stats"; - } - - @RequestMapping({"contact", "contact/"}) - public String showContactPage(ModelMap m) { - - return "contact"; - } - @PreAuthorize("hasRole('ROLE_USER')") // TODO: this probably shouldn't be here - @RequestMapping("manage/**") - public String showClientManager(ModelMap m) { - return "manage"; - } + @RequestMapping({"", "home", "index"}) + public String showHomePage(ModelMap m) { + + Map summary = statsService.calculateSummaryStats(); + + m.put("statsSummary", summary); + return "home"; + } + + @RequestMapping({"about", "about/"}) + public String showAboutPage(ModelMap m) { + + return "about"; + } + + @RequestMapping({"stats", "stats/"}) + public String showStatsPage(ModelMap m) { + + Map summary = statsService.calculateSummaryStats(); + + m.put("statsSummary", summary); + return "stats"; + } + + @RequestMapping({"contact", "contact/"}) + public String showContactPage(ModelMap m) { + + return "contact"; + } + + @PreAuthorize("hasRole('ROLE_USER')") // TODO: this probably shouldn't be here + @RequestMapping("manage/**") + public String showClientManager(ModelMap m) { + return "manage"; + } public StatsService getStatsService() { return statsService; diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ServerConfigInterceptor.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ServerConfigInterceptor.java index e81ec11a5..a7bf54c2b 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ServerConfigInterceptor.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ServerConfigInterceptor.java @@ -13,7 +13,7 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; /** * - * Injects the server configuration bean into the Model context, if it exists. Allows JSPs and the like to call "config.logoUrl" among others. + * Injects the server configuration bean into the Model context, if it exists. Allows JSPs and the like to call "config.logoUrl" among others. * * @author jricher * @@ -22,12 +22,12 @@ public class ServerConfigInterceptor extends HandlerInterceptorAdapter { @Autowired private ConfigurationPropertiesBean config; - - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - if (modelAndView != null) { // skip checking at all if we have no model and view to hand the config to - modelAndView.addObject("config", config); - } - } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + if (modelAndView != null) { // skip checking at all if we have no model and view to hand the config to + modelAndView.addObject("config", config); + } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/StatsAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/StatsAPI.java index 0da17073b..fb23f3b12 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/StatsAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/StatsAPI.java @@ -13,19 +13,19 @@ import org.springframework.web.bind.annotation.RequestMapping; @PreAuthorize("hasRole('ROLE_USER')") @RequestMapping("stats") public class StatsAPI { - + @Autowired private StatsService statsService; - + @RequestMapping(value = "summary", produces = "application/json") public String statsSummary(ModelMap m) { - + Map e = statsService.calculateSummaryStats(); - + m.put("entity", e); - + return "statsSummaryJson"; - + } - + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java index 4e6625fc7..d559a1863 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java @@ -45,23 +45,23 @@ import com.google.common.collect.ImmutableMap; */ @Controller public class UserInfoEndpoint { - + @Autowired private UserInfoService userInfoService; - + private static Logger logger = LoggerFactory.getLogger(UserInfoEndpoint.class); - + private Map schemaToViewNameMap = ImmutableMap.of( - openIdSchema, jsonUserInfoViewName, + openIdSchema, jsonUserInfoViewName, pocoSchema, pocoUserInfoViewName - ); - + ); + // Valid schemas and associated views private static final String openIdSchema = "openid"; private static final String pocoSchema = "poco"; private static final String jsonUserInfoViewName = "jsonUserInfoView"; private static final String pocoUserInfoViewName = "pocoUserInfoView"; - + /** * Get information about the user as specified in the accessToken->idToken included in this request * @@ -81,45 +81,45 @@ public class UserInfoEndpoint { String viewName = schemaToViewNameMap.get(schema); if (viewName == null) { - logger.error("getInfo failed; unknown User Info schema " + schema); + logger.error("getInfo failed; unknown User Info schema " + schema); model.addAttribute("code", HttpStatus.BAD_REQUEST); return "httpCodeView"; } - String userId = p.getName(); + String userId = p.getName(); UserInfo userInfo = userInfoService.getBySubject(userId); - + if (userInfo == null) { - logger.error("getInfo failed; user not found: " + userId); + logger.error("getInfo failed; user not found: " + userId); model.addAttribute("code", HttpStatus.NOT_FOUND); return "httpCodeView"; } - + if (p instanceof OAuth2Authentication) { - OAuth2Authentication authentication = (OAuth2Authentication)p; - - model.addAttribute("scope", authentication.getOAuth2Request().getScope()); - model.addAttribute("requestObject", authentication.getOAuth2Request().getRequestParameters().get("request")); - } + OAuth2Authentication authentication = (OAuth2Authentication)p; + + model.addAttribute("scope", authentication.getOAuth2Request().getScope()); + model.addAttribute("requestObject", authentication.getOAuth2Request().getRequestParameters().get("request")); + } model.addAttribute("userInfo", userInfo); - + return viewName; } /** - * @return the schemaToViewNameMap (defaults to an immutable map) - */ - public Map getSchemaToViewNameMap() { - return schemaToViewNameMap; - } + * @return the schemaToViewNameMap (defaults to an immutable map) + */ + public Map getSchemaToViewNameMap() { + return schemaToViewNameMap; + } /** - * @param schemaToViewNameMap the schemaToViewNameMap to set - */ - public void setSchemaToViewNameMap(Map schemaToViewNameMap) { - this.schemaToViewNameMap = schemaToViewNameMap; - } + * @param schemaToViewNameMap the schemaToViewNameMap to set + */ + public void setSchemaToViewNameMap(Map schemaToViewNameMap) { + this.schemaToViewNameMap = schemaToViewNameMap; + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java index f9ee36a1b..6719df467 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java @@ -9,7 +9,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.repository.UserInfoRepository; import org.mitre.openid.connect.service.UserInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.ModelAndView; @@ -25,29 +24,29 @@ public class UserInfoInterceptor extends HandlerInterceptorAdapter { @Autowired private UserInfoService userInfoService; - - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - if (modelAndView != null) { // skip checking at all if we have no model and view to hand the user to - // get our principal from the security context - Principal p = request.getUserPrincipal(); - - if (p != null && p.getName() != null) { // don't bother checking if we don't have a principal - - // try to look up a user based on it - UserInfo user = userInfoService.getBySubject(p.getName()); - - // if we have one, inject it so views can use it - if (user != null) { - modelAndView.addObject("userInfo", user); - } - } - } - - } - - - + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + + if (modelAndView != null) { // skip checking at all if we have no model and view to hand the user to + // get our principal from the security context + Principal p = request.getUserPrincipal(); + + if (p != null && p.getName() != null) { // don't bother checking if we don't have a principal + + // try to look up a user based on it + UserInfo user = userInfoService.getBySubject(p.getName()); + + // if we have one, inject it so views can use it + if (user != null) { + modelAndView.addObject("userInfo", user); + } + } + } + + } + + + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/WhitelistAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/WhitelistAPI.java index 43a8ed21d..c95d7b12b 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/WhitelistAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/WhitelistAPI.java @@ -36,12 +36,12 @@ public class WhitelistAPI { @Autowired private WhitelistedSiteService whitelistService; - + private static Logger logger = LoggerFactory.getLogger(WhitelistAPI.class); - + private Gson gson = new Gson(); private JsonParser parser = new JsonParser(); - + /** * Get a list of all whitelisted sites * @param m @@ -49,14 +49,14 @@ public class WhitelistAPI { */ @RequestMapping(method = RequestMethod.GET, produces = "application/json") public String getAllWhitelistedSites(ModelMap m) { - + Collection all = whitelistService.getAll(); - + m.put("entity", all); - + return "jsonEntityView"; } - + /** * Create a new whitelisted site * @param jsonString @@ -67,10 +67,10 @@ public class WhitelistAPI { @PreAuthorize("hasRole('ROLE_ADMIN')") @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public String addNewWhitelistedSite(@RequestBody String jsonString, ModelMap m, Principal p) { - - JsonObject json; - - WhitelistedSite whitelist = null; + + JsonObject json; + + WhitelistedSite whitelist = null; try { json = parser.parse(jsonString).getAsJsonObject(); whitelist = gson.fromJson(json, WhitelistedSite.class); @@ -86,28 +86,28 @@ public class WhitelistAPI { m.addAttribute("errorMessage", "Could not save new whitelisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); return "jsonErrorView"; } - + // save the id of the person who created this whitelist.setCreatorUserId(p.getName()); - + WhitelistedSite newWhitelist = whitelistService.saveNew(whitelist); - + m.put("entity", newWhitelist); - + return "jsonEntityView"; - + } - + /** * Update an existing whitelisted site */ @PreAuthorize("hasRole('ROLE_ADMIN')") @RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json") public String updateWhitelistedSite(@PathVariable("id") Long id, @RequestBody String jsonString, ModelMap m, Principal p) { - - JsonObject json; - - WhitelistedSite whitelist = null; + + JsonObject json; + + WhitelistedSite whitelist = null; try { json = parser.parse(jsonString).getAsJsonObject(); whitelist = gson.fromJson(json, WhitelistedSite.class); @@ -123,24 +123,24 @@ public class WhitelistAPI { m.put("errorMessage", "Could not update whitelisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance."); return "jsonErrorView"; } - + WhitelistedSite oldWhitelist = whitelistService.getById(id); - + if (oldWhitelist == null) { logger.error("updateWhitelistedSite failed; whitelist with id " + id + " could not be found."); m.put("code", HttpStatus.NOT_FOUND); m.put("errorMessage", "Could not update whitelisted site. The requested whitelisted site with id " + id + "could not be found."); return "jsonErrorView"; } else { - + WhitelistedSite newWhitelist = whitelistService.update(oldWhitelist, whitelist); - + m.put("entity", newWhitelist); - + return "jsonEntityView"; } } - + /** * Delete a whitelisted site * @@ -149,7 +149,7 @@ public class WhitelistAPI { @RequestMapping(value="/{id}", method = RequestMethod.DELETE) public String deleteWhitelistedSite(@PathVariable("id") Long id, ModelMap m) { WhitelistedSite whitelist = whitelistService.getById(id); - + if (whitelist == null) { logger.error("deleteWhitelistedSite failed; whitelist with id " + id + " could not be found."); m.put("code", HttpStatus.NOT_FOUND); @@ -158,11 +158,11 @@ public class WhitelistAPI { } else { m.put("code", HttpStatus.OK); whitelistService.remove(whitelist); - } - + } + return "httpCodeView"; } - + /** * Get a single whitelisted site */ @@ -175,11 +175,11 @@ public class WhitelistAPI { m.put("errorMessage", "The requested whitelisted site with id " + id + "could not be found."); return "jsonErrorView"; } else { - + m.put("entity", whitelist); - + return "jsonEntityView"; } - + } } diff --git a/openid-connect-server/src/main/resources/log4j.xml b/openid-connect-server/src/main/resources/log4j.xml index 645b8595a..2774f58ea 100644 --- a/openid-connect-server/src/main/resources/log4j.xml +++ b/openid-connect-server/src/main/resources/log4j.xml @@ -9,21 +9,21 @@ - + - + - + - + @@ -37,5 +37,5 @@ - + diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/aboutContent.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/aboutContent.tag index eb4fd6e5c..3eddab0a0 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/aboutContent.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/aboutContent.tag @@ -1,8 +1,9 @@

About

-

-This OpenID Connect service is built from the MITREid Connect Open Source project started by The MITRE Corporation. -

+

This OpenID Connect service is built from the MITREid Connect + Open Source project started by The MITRE Corporation.

-More information about the project can be found on our GitHub page: MTIREid Connect on GitHub -There, you can submit bug reports, give feedback, or even contribute code patches for additional features you'd like to see. + More information about the project can be found on our GitHub page: MTIREid Connect on + GitHub There, you can submit bug reports, give feedback, or even + contribute code patches for additional features you'd like to see.

\ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/actionmenu.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/actionmenu.tag index 571c3c547..5848524e3 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/actionmenu.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/actionmenu.tag @@ -1,12 +1,13 @@ <%@ tag language="java" pageEncoding="UTF-8"%> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> +<%@ taglib prefix="security" + uri="http://www.springframework.org/security/tags"%> - -
  • Manage Clients
  • -
  • Whitelisted Clients
  • -
  • Blacklisted Clients
  • -
  • System Scopes
  • -
  • + +
  • Manage Clients
  • +
  • Whitelisted Clients
  • +
  • Blacklisted Clients
  • +
  • System Scopes
  • +
  • Manage Sites
  • diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/breadcrumbs.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/breadcrumbs.tag index 833cca39f..219d5161e 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/breadcrumbs.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/breadcrumbs.tag @@ -1,2 +1,2 @@ -<%@attribute name="crumb" required="false" %> +<%@attribute name="crumb" required="false"%> \ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/contactContent.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/contactContent.tag index 6d74c9747..29a83124f 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/contactContent.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/contactContent.tag @@ -1,6 +1,9 @@ -

    Contact

    -

    -For general assistance, email Bob at email@address.com. -To offer feedback, email Sue at email@address.com. -To report a system failure or bug report, email Joe at email@address.com. +

    Contact

    +

    + For general assistance, email Bob at email@address.com. + To offer feedback, email Sue at email@address.com. + To report a system failure or bug report, email Joe at email@address.com.

    diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/copyright.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/copyright.tag index 9a5d852c7..3d2961b64 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/copyright.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/copyright.tag @@ -1 +1,3 @@ -Powered by MITREid Connect © 2013 The MITRE Corporation. \ No newline at end of file +Powered by +MITREid Connect +© 2013 The MITRE Corporation. diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/footer.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/footer.tag index 6938abc21..55f522bc6 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/footer.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/footer.tag @@ -1,28 +1,33 @@ -<%@attribute name="js" required="false" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="o" tagdir="/WEB-INF/tags" %> +<%@attribute name="js" required="false"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%>
    - + + - + - + - - - - - + + + + + \ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/tags/header.tag b/openid-connect-server/src/main/webapp/WEB-INF/tags/header.tag index d644d70e3..51fd702d6 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/tags/header.tag +++ b/openid-connect-server/src/main/webapp/WEB-INF/tags/header.tag @@ -1,119 +1,123 @@ -<%@attribute name="title" required="false" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@attribute name="title" required="false"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> - ${pageContext.request.requestURL} - +${pageContext.request.requestURL} + - - OpenID Connect - ${title} - - - + +OpenID Connect - ${title} + + + - - - - - +.credit { + margin: 20px 0; +} - - + - - - - - + + + + + - - + + - \ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/views/about.jsp b/openid-connect-server/src/main/webapp/WEB-INF/views/about.jsp index 05c653297..9114e3f7e 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/views/about.jsp +++ b/openid-connect-server/src/main/webapp/WEB-INF/views/about.jsp @@ -1,24 +1,25 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="o" tagdir="/WEB-INF/tags" %> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%> +<%@ taglib prefix="security" + uri="http://www.springframework.org/security/tags"%> - - + +
    -
    - -
    - -
    +
    + +
    + +
    - + -
    +
    -
    -
    +
    +
    - \ No newline at end of file + \ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/views/contact.jsp b/openid-connect-server/src/main/webapp/WEB-INF/views/contact.jsp index 68d322c69..c99146e98 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/views/contact.jsp +++ b/openid-connect-server/src/main/webapp/WEB-INF/views/contact.jsp @@ -1,23 +1,24 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="o" tagdir="/WEB-INF/tags" %> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%> +<%@ taglib prefix="security" + uri="http://www.springframework.org/security/tags"%> - - + +
    -
    - -
    -
    +
    + +
    +
    - + -
    +
    -
    -
    +
    +
    - \ No newline at end of file + \ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/views/exception/usernotfound.jsp b/openid-connect-server/src/main/webapp/WEB-INF/views/exception/usernotfound.jsp index 3f40d453d..7b87bbb02 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/views/exception/usernotfound.jsp +++ b/openid-connect-server/src/main/webapp/WEB-INF/views/exception/usernotfound.jsp @@ -1,5 +1,5 @@ <%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> + pageEncoding="ISO-8859-1"%> @@ -7,7 +7,7 @@ User Not Found -<% response.setStatus(404); %> -

    Error: requested user was not found

    + <% response.setStatus(404); %> +

    Error: requested user was not found

    \ No newline at end of file diff --git a/openid-connect-server/src/main/webapp/WEB-INF/views/home.jsp b/openid-connect-server/src/main/webapp/WEB-INF/views/home.jsp index 4e32d091e..beddcf322 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/views/home.jsp +++ b/openid-connect-server/src/main/webapp/WEB-INF/views/home.jsp @@ -1,35 +1,36 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="o" tagdir="/WEB-INF/tags" %> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%> +<%@ taglib prefix="security" + uri="http://www.springframework.org/security/tags"%> - +
    -
    - -
    -
    - -
    - -
    -
    - -
    -
    - -
    +
    + +
    +
    + +
    + +
    +
    + +
    +
    + +
    -
    -
    - -
    -
    - -
    -
    +
    +
    + +
    +
    + +
    +
    -
    -
    +
    +
    - + diff --git a/openid-connect-server/src/main/webapp/WEB-INF/views/login.jsp b/openid-connect-server/src/main/webapp/WEB-INF/views/login.jsp index f7bbebe81..3e098af3e 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/views/login.jsp +++ b/openid-connect-server/src/main/webapp/WEB-INF/views/login.jsp @@ -1,7 +1,8 @@ -<%@ taglib prefix="authz" uri="http://www.springframework.org/security/tags" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="o" tagdir="/WEB-INF/tags" %> - +<%@ taglib prefix="authz" + uri="http://www.springframework.org/security/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%> +