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 f6506450a..dd35f4edf 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 @@ -97,7 +97,7 @@ public class IntrospectingTokenService implements ResourceServerTokenServices { public void setIntrospectionConfigurationService(IntrospectionConfigurationService introspectionUrlProvider) { this.introspectionConfigurationService = introspectionUrlProvider; } - + /** * @param introspectionAuthorityGranter the introspectionAuthorityGranter to set */ @@ -111,7 +111,7 @@ public class IntrospectingTokenService implements ResourceServerTokenServices { public IntrospectionAuthorityGranter getIntrospectionAuthorityGranter() { return introspectionAuthorityGranter; } - + // Check if there is a token and authentication in the cache // and check if it is not expired. private TokenCacheObject checkCache(String key) { 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 a95236297..663711ec2 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 @@ -96,10 +96,10 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi @Autowired private JWKSetCacheService validationServices; - + @Autowired(required=false) private SymmetricCacheService symmetricCacheService; - + @Autowired(required=false) private JwtSigningAndValidationService authenticationSignerService; @@ -113,7 +113,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi // private helpers to handle target link URLs private TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler = new TargetLinkURIAuthenticationSuccessHandler(); private TargetLinkURIChecker deepLinkFilter; - + protected int httpSocketTimeout = HTTP_SOCKET_TIMEOUT; /** @@ -128,17 +128,17 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi @Override public void afterPropertiesSet() { super.afterPropertiesSet(); - + // if our JOSE validators don't get wired in, drop defaults into place - + if (validationServices == null) { validationServices = new JWKSetCacheService(); } - + if (symmetricCacheService == null) { symmetricCacheService = new SymmetricCacheService(); } - + } /* @@ -206,7 +206,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi // there's a target URL in the response, we should save this so we can forward to it later session.setAttribute(TARGET_SESSION_VARIABLE, issResp.getTargetLinkUri()); } - + if (Strings.isNullOrEmpty(issuer)) { logger.error("No issuer found: " + issuer); throw new AuthenticationServiceException("No issuer found: " + issuer); @@ -315,37 +315,37 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi return httpRequest; } }; - } else { + } else { // we're not doing basic auth, figure out what other flavor we have restTemplate = new RestTemplate(factory); if (SECRET_JWT.equals(clientConfig.getTokenEndpointAuthMethod()) || PRIVATE_KEY.equals(clientConfig.getTokenEndpointAuthMethod())) { // do a symmetric secret signed JWT for auth - - + + JwtSigningAndValidationService signer = null; JWSAlgorithm alg = clientConfig.getTokenEndpointAuthSigningAlg(); - + if (SECRET_JWT.equals(clientConfig.getTokenEndpointAuthMethod()) && (alg.equals(JWSAlgorithm.HS256) - || alg.equals(JWSAlgorithm.HS384) - || alg.equals(JWSAlgorithm.HS512))) { - + || alg.equals(JWSAlgorithm.HS384) + || alg.equals(JWSAlgorithm.HS512))) { + // generate one based on client secret signer = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient()); - + } else if (PRIVATE_KEY.equals(clientConfig.getTokenEndpointAuthMethod())) { - + // needs to be wired in to the bean signer = authenticationSignerService; } - + if (signer == null) { throw new AuthenticationServiceException("Couldn't find required signer service for use with private key auth."); } - + JWTClaimsSet claimsSet = new JWTClaimsSet(); - + claimsSet.setIssuer(clientConfig.getClientId()); claimsSet.setSubject(clientConfig.getClientId()); claimsSet.setAudience(Lists.newArrayList(serverConfig.getTokenEndpointUri())); @@ -353,15 +353,15 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi // TODO: make this configurable Date exp = new Date(System.currentTimeMillis() + (60 * 1000)); // auth good for 60 seconds claimsSet.setExpirationTime(exp); - + Date now = new Date(System.currentTimeMillis()); claimsSet.setIssueTime(now); claimsSet.setNotBeforeTime(now); - + SignedJWT jwt = new SignedJWT(new JWSHeader(alg), claimsSet); - - signer.signJwt(jwt, alg); - + + signer.signJwt(jwt, alg); + form.add("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"); form.add("client_assertion", jwt.serialize()); } else { @@ -369,7 +369,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi form.add("client_id", clientConfig.getClientId()); form.add("client_secret", clientConfig.getClientSecret()); } - + } logger.debug("tokenEndpointURI = " + serverConfig.getTokenEndpointUri()); @@ -630,22 +630,22 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected class TargetLinkURIAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private AuthenticationSuccessHandler passthrough; - + @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) - throws IOException, ServletException { - + throws IOException, ServletException { + HttpSession session = request.getSession(); - + // check to see if we've got a target String target = getStoredSessionString(session, TARGET_SESSION_VARIABLE); - + if (!Strings.isNullOrEmpty(target)) { session.removeAttribute(TARGET_SESSION_VARIABLE); - + target = deepLinkFilter.filter(target); - + response.sendRedirect(target); } else { // if the target was blank, use the default behavior here diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/StaticPrefixTargetLinkURIChecker.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/StaticPrefixTargetLinkURIChecker.java index c8953514d..7ce08da57 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/StaticPrefixTargetLinkURIChecker.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/StaticPrefixTargetLinkURIChecker.java @@ -10,7 +10,7 @@ package org.mitre.openid.connect.client; public class StaticPrefixTargetLinkURIChecker implements TargetLinkURIChecker { private String prefix = ""; - + @Override public String filter(String target) { if (target == null) { diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/DynamicServerConfigurationService.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/DynamicServerConfigurationService.java index fa6f9b13e..0e99633ca 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/DynamicServerConfigurationService.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/service/impl/DynamicServerConfigurationService.java @@ -48,13 +48,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import static org.mitre.discovery.util.JsonUtils.getAsBoolean; -import static org.mitre.discovery.util.JsonUtils.getAsEncryptionMethodList; -import static org.mitre.discovery.util.JsonUtils.getAsJweAlgorithmList; -import static org.mitre.discovery.util.JsonUtils.getAsJwsAlgorithmList; -import static org.mitre.discovery.util.JsonUtils.getAsString; -import static org.mitre.discovery.util.JsonUtils.getAsStringList; - /** * * Dynamically fetches OpenID Connect server configurations based on the issuer. Caches the server configurations. diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetCacheService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetCacheService.java index 1eafbb271..81abdd2f0 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetCacheService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JWKSetCacheService.java @@ -23,7 +23,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.apache.http.client.HttpClient; -import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.SystemDefaultHttpClient; import org.mitre.jose.keystore.JWKSetKeyStore; import org.mitre.jwt.encryption.service.JwtEncryptionAndDecryptionService; @@ -130,10 +129,10 @@ public class JWKSetCacheService { } /** - * @author jricher - * - */ - private class JWKSetEncryptorFetcher extends CacheLoader { + * @author jricher + * + */ + private class JWKSetEncryptorFetcher extends CacheLoader { private HttpClient httpClient = new SystemDefaultHttpClient(); private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient); private RestTemplate restTemplate = new RestTemplate(httpFactory); diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/SymmetricCacheService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/SymmetricCacheService.java index c4bc943b7..84add9907 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/SymmetricCacheService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/SymmetricCacheService.java @@ -31,11 +31,11 @@ import com.nimbusds.jose.util.Base64URL; */ @Service public class SymmetricCacheService { - + private static Logger logger = LoggerFactory.getLogger(SymmetricCacheService.class); - + private LoadingCache validators; - + public SymmetricCacheService() { validators = CacheBuilder.newBuilder() @@ -43,8 +43,8 @@ public class SymmetricCacheService { .maximumSize(100) .build(new SymmetricValidatorBuilder()); } - - + + /** * Create a symmetric signing and validation service for the given client * @@ -62,7 +62,7 @@ public class SymmetricCacheService { logger.error("Couldn't create symmetric validator for client " + client.getClientId() + " without a client secret"); return null; } - + try { return validators.get(client.getClientSecret()); } catch (UncheckedExecutionException ue) { @@ -72,28 +72,28 @@ public class SymmetricCacheService { logger.error("Problem loading client validator", e); return null; } - + } - + public class SymmetricValidatorBuilder extends CacheLoader { @Override public JwtSigningAndValidationService load(String key) throws Exception { try { - + String id = "SYMMETRIC-KEY"; - + JWK jwk = new OctetSequenceKey(Base64URL.encode(key), Use.SIGNATURE, null, id, null, null, null); Map keys = ImmutableMap.of(id, jwk); JwtSigningAndValidationService service = new DefaultJwtSigningAndValidationService(keys); - + return service; - + } catch (NoSuchAlgorithmException e) { logger.error("Couldn't create symmetric validator for client", e); } catch (InvalidKeySpecException e) { logger.error("Couldn't create symmetric validator for client", e); } - + throw new IllegalArgumentException("Couldn't create symmetric validator for client"); } 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 c9777e3ef..82bc533a8 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 @@ -351,14 +351,14 @@ public class ClientDetailsEntity implements ClientDetails { @Override @Transient public boolean isSecretRequired() { - if (getTokenEndpointAuthMethod() != null && + if (getTokenEndpointAuthMethod() != null && getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) || getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)) { return true; } else { return false; } - + } /** 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 ab7289c8d..9c081a58c 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 @@ -32,7 +32,7 @@ public interface AuthenticationHolderRepository { public void remove(AuthenticationHolderEntity a); public AuthenticationHolderEntity save(AuthenticationHolderEntity a); - + public List getOrphanedAuthenticationHolders(); 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 57201cc17..a81cccac9 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 @@ -57,7 +57,7 @@ public interface OAuth2TokenRepository { public Set getAllAccessTokens(); public Set getAllRefreshTokens(); - + public Set getAllExpiredAccessTokens(); public Set getAllExpiredRefreshTokens(); diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java index efd5867c8..ecb0f9a95 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java @@ -22,8 +22,6 @@ import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.springframework.security.oauth2.provider.OAuth2Request; -import com.nimbusds.jose.JWSAlgorithm; - /** * Service to create specialty OpenID Connect tokens. * @@ -62,5 +60,5 @@ public interface OIDCTokenService { * @return */ public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client); - + } \ No newline at end of file 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 319987b82..7ca425350 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 @@ -51,7 +51,7 @@ public interface StatsService { * @return */ public Integer getCountForClientId(Long id); - + /** * Trigger the stats to be recalculated upon next update. */ diff --git a/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java b/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java index 172c8b4ab..c8f8f28c7 100644 --- a/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java @@ -113,8 +113,8 @@ public class DiscoveryEndpoint { model.addAttribute("code", HttpStatus.NOT_FOUND); return "httpCodeView"; } - - + + } else { logger.info("Unknown URI format: " + resource); model.addAttribute("code", HttpStatus.NOT_FOUND); @@ -261,7 +261,7 @@ public class DiscoveryEndpoint { Collection serverSigningAlgs = signService.getAllSigningAlgsSupported(); Collection clientSymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512); Collection clientSymmetricAndAsymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512); - + Map m = new HashMap(); m.put("issuer", config.getIssuer()); m.put("authorization_endpoint", baseUrl + "authorize"); 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 873ea5e2a..afb4e1779 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 @@ -33,8 +33,8 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class JpaAuthenticationHolderRepository implements AuthenticationHolderRepository { - private static final int MAXEXPIREDRESULTS = 1000; - + private static final int MAXEXPIREDRESULTS = 1000; + @PersistenceContext private EntityManager manager; @@ -77,7 +77,7 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe public AuthenticationHolderEntity save(AuthenticationHolderEntity a) { return JpaUtil.saveOrUpdate(a.getId(), manager, a); } - + @Override @Transactional public List getOrphanedAuthenticationHolders() { 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 141501f06..2cd217fda 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 @@ -181,7 +181,7 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository { List accessTokens = queryA.getResultList(); return JpaUtil.getSingleResult(accessTokens); } - + @Override public Set getAllExpiredAccessTokens() { TypedQuery query = manager.createNamedQuery("OAuth2AccessTokenEntity.getAllExpiredByDate", OAuth2AccessTokenEntity.class); 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 2e9b854bd..d74449ce3 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 @@ -78,7 +78,7 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt @Autowired private SystemScopeService scopeService; - + @Autowired private StatsService statsService; @@ -142,9 +142,9 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt client.setScope(scopeService.removeRestrictedScopes(client.getScope())); ClientDetailsEntity c = clientRepository.saveClient(client); - + statsService.resetCache(); - + return c; } @@ -202,14 +202,14 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt clientRepository.deleteClient(client); statsService.resetCache(); - + } /** * Update the oldClient with information from the newClient. The * id from oldClient is retained. * - * Checks to make sure the refresh grant type and + * Checks to make sure the refresh grant type and * the scopes are set appropriately. * * Checks to make sure the redirect URIs aren't blacklisted. 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 ab62eaf3d..9aeff131e 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 @@ -51,8 +51,6 @@ import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.stereotype.Service; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; import com.google.common.collect.Sets; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.PlainJWT; @@ -404,8 +402,8 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) { try { revokeAccessToken(oAuth2AccessTokenEntity); - } catch (IllegalArgumentException e) { - //An ID token is deleted with its corresponding access token, but then the ID token is on the list of expired tokens as well and there is + } catch (IllegalArgumentException e) { + //An ID token is deleted with its corresponding access token, but then the ID token is on the list of expired tokens as well and there is //nothing in place to distinguish it from any other. //An attempt to delete an already deleted token returns an error, stopping the cleanup dead. We need it to keep going. } @@ -416,7 +414,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) { revokeRefreshToken(oAuth2RefreshTokenEntity); } - + Collection authHolders = getOrphanedAuthenticationHolders(); logger.info("Found " + authHolders.size() + " orphaned authentication holders"); for(AuthenticationHolderEntity authHolder : authHolders) { @@ -431,7 +429,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi private Collection getExpiredRefreshTokens() { return Sets.newHashSet(tokenRepository.getAllExpiredRefreshTokens()); } - + private Collection getOrphanedAuthenticationHolders() { return Sets.newHashSet(authenticationHolderRepository.getOrphanedAuthenticationHolders()); } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenApiView.java b/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenApiView.java index 3ce1900cc..70e6e2002 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenApiView.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenApiView.java @@ -58,22 +58,22 @@ public class TokenApiView extends AbstractView { JsonObject o = new JsonObject(); - + o.addProperty("value", src.getValue()); o.addProperty("id", src.getId()); o.addProperty("idTokenId", src.getIdToken() != null ? src.getIdToken().getId() : null); o.addProperty("refreshTokenId", src.getRefreshToken() != null ? src.getRefreshToken().getId() : null); o.add("scopes", context.serialize(src.getScope())); - + o.addProperty("clientId", src.getClient().getClientId()); o.addProperty("userId", src.getAuthenticationHolder().getAuthentication().getName()); - + o.add("expiration", context.serialize(src.getExpiration())); - + return o; } - + }) .registerTypeAdapter(OAuth2RefreshTokenEntity.class, new JsonSerializer() { @@ -81,20 +81,20 @@ public class TokenApiView extends AbstractView { public JsonElement serialize(OAuth2RefreshTokenEntity src, Type typeOfSrc, JsonSerializationContext context) { JsonObject o = new JsonObject(); - + o.addProperty("value", src.getValue()); o.addProperty("id", src.getId()); o.add("scopes", context.serialize(src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getScope())); - + o.addProperty("clientId", src.getClient().getClientId()); o.addProperty("userId", src.getAuthenticationHolder().getAuthentication().getName()); - + o.add("expiration", context.serialize(src.getExpiration())); - + return o; } - + }) .serializeNulls() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") 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 af5e69673..39106cb1b 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 @@ -69,13 +69,13 @@ public class OAuthConfirmationController { @Autowired private ScopeClaimTranslationService scopeClaimTranslationService; - + @Autowired private UserInfoService userInfoService; - + @Autowired private StatsService statsService; - + private static Logger logger = LoggerFactory.getLogger(OAuthConfirmationController.class); public OAuthConfirmationController() { @@ -131,7 +131,7 @@ public class OAuthConfirmationController { model.put("redirect_uri", redirect_uri); - + // pre-process the scopes Set scopes = scopeService.fromStrings(authRequest.getScope()); @@ -157,7 +157,7 @@ public class OAuthConfirmationController { for (SystemScope systemScope : sortedScopes) { Map claimValues = new HashMap(); - + Set claims = scopeClaimTranslationService.getClaimsForScope(systemScope.getValue()); for (String claim : claims) { if (userJson.has(claim) && userJson.get(claim).isJsonPrimitive()) { @@ -165,23 +165,23 @@ public class OAuthConfirmationController { claimValues.put(claim, userJson.get(claim).getAsString()); } } - + claimsForScopes.put(systemScope.getValue(), claimValues); } - + model.put("claims", claimsForScopes); // client stats Integer count = statsService.getCountForClientId(client.getId()); model.put("count", count); - - + + // contacts if (client.getContacts() != null) { String contacts = Joiner.on(", ").join(client.getContacts()); model.put("contacts", contacts); } - + // if the client is over a week old and has more than one registration, don't give such a big warning // instead, tag as "Generally Recognized As Safe (gras) Date lastWeek = new Date(System.currentTimeMillis() + (60 * 60 * 24 * 7 * 1000)); @@ -191,10 +191,10 @@ public class OAuthConfirmationController { } else { model.put("gras", false); } - + // inject a random value for CSRF purposes model.put("csrf", authRequest.getExtensions().get("csrf")); - + return "approve"; } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java index 5cd38babf..cd5f44a83 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java @@ -76,7 +76,7 @@ public class TokenAPI { return "tokenApiView"; } } - + @RequestMapping(value = "/access/{id}", method = RequestMethod.DELETE, produces = "application/json") public String deleteAccessTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) { @@ -94,19 +94,19 @@ public class TokenAPI { return "jsonErrorView"; } else { tokenService.revokeAccessToken(token); - - return "httpCodeView"; + + return "httpCodeView"; } } - + @RequestMapping(value = "/refresh", method = RequestMethod.GET, produces = "application/json") public String getAllRefreshTokens(ModelMap m, Principal p) { - + Set allTokens = tokenService.getAllRefreshTokensForUser(p.getName()); m.put("entity", allTokens); return "tokenApiView"; - - + + } @RequestMapping(value = "/refresh/{id}", method = RequestMethod.GET, produces = "application/json") @@ -129,7 +129,7 @@ public class TokenAPI { return "tokenApiView"; } } - + @RequestMapping(value = "/refresh/{id}", method = RequestMethod.DELETE, produces = "application/json") public String deleteRefreshTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) { @@ -147,9 +147,9 @@ public class TokenAPI { return "jsonErrorView"; } else { tokenService.revokeRefreshToken(token); - - return "httpCodeView"; + + return "httpCodeView"; } } - + } 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 0a738a511..c7ed19684 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 @@ -61,7 +61,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { @Autowired private JWKSetCacheService validators; - + @Autowired private SymmetricCacheService symmetricCacheService; @@ -124,12 +124,12 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { if (request.getClientId() != null) { try { ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId()); - + if ((request.getScope() == null || request.getScope().isEmpty())) { Set clientScopes = client.getScope(); request.setScope(clientScopes); } - + if (request.getExtensions().get("max_age") == null && client.getDefaultMaxAge() != null) { request.getExtensions().put("max_age", client.getDefaultMaxAge().toString()); } @@ -138,12 +138,12 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { } } - + // add CSRF protection to the request on first parse String csrf = UUID.randomUUID().toString(); - request.getExtensions().put("csrf", csrf); + request.getExtensions().put("csrf", csrf); + - return request; } @@ -180,7 +180,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { JWSAlgorithm alg = signedJwt.getHeader().getAlgorithm(); if (client.getRequestObjectSigningAlg() == null || - !client.getRequestObjectSigningAlg().equals(alg)) { + !client.getRequestObjectSigningAlg().equals(alg)) { throw new InvalidClientException("Client's registered request object signing algorithm (" + client.getRequestObjectSigningAlg() + ") does not match request object's actual algorithm (" + alg.getName() + ")"); } 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 39d5387e6..581405158 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 @@ -32,6 +32,10 @@ import com.nimbusds.jwt.JWT; */ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticationToken { + /** + * + */ + private static final long serialVersionUID = -3138213539914074617L; private String clientId; private JWT jwt; 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 59c989b82..a73536133 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 @@ -55,7 +55,7 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { // map of verifiers, load keys for clients @Autowired private JWKSetCacheService validators; - + // map of symmetric verifiers for client secrets @Autowired private SymmetricCacheService symmetricCacheService; @@ -92,15 +92,15 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { JWSAlgorithm alg = jws.getHeader().getAlgorithm(); - if (client.getTokenEndpointAuthSigningAlg() != null && + if (client.getTokenEndpointAuthSigningAlg() != null && !client.getTokenEndpointAuthSigningAlg().equals(alg)) { throw new InvalidClientException("Client's registered request object signing algorithm (" + client.getRequestObjectSigningAlg() + ") does not match request object's actual algorithm (" + alg.getName() + ")"); } if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) && (alg.equals(JWSAlgorithm.RS256) - || alg.equals(JWSAlgorithm.RS384) - || alg.equals(JWSAlgorithm.RS512))) { + || alg.equals(JWSAlgorithm.RS384) + || alg.equals(JWSAlgorithm.RS512))) { JwtSigningAndValidationService validator = validators.getValidator(client.getJwksUri()); @@ -113,24 +113,24 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider { } } else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT) && (alg.equals(JWSAlgorithm.HS256) - || alg.equals(JWSAlgorithm.HS384) - || alg.equals(JWSAlgorithm.HS512))) { + || alg.equals(JWSAlgorithm.HS384) + || alg.equals(JWSAlgorithm.HS512))) { // it's HMAC, we need to make a validator based on the client secret - + JwtSigningAndValidationService validator = symmetricCacheService.getSymmetricValidtor(client); - + if (validator == null) { throw new AuthenticationServiceException("Unable to create signature validator for client's secret: " + client.getClientSecret()); } - + if (!validator.validateSignature(jws)) { throw new AuthenticationServiceException("Signature did not validate for presented JWT authentication."); } - + } } - + // check the issuer if (jwtClaims.getIssuer() == null) { throw new AuthenticationServiceException("Assertion Token Issuer is null"); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java index fc3f7570b..23da6f8aa 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java @@ -42,7 +42,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.security.oauth2.provider.OAuth2RequestFactory; import org.springframework.stereotype.Component; @@ -68,7 +67,7 @@ public class PromptFilter extends GenericFilterBean { @Autowired private ClientDetailsEntityService clientService; - + /** * */ @@ -77,7 +76,7 @@ public class PromptFilter extends GenericFilterBean { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; - + // skip everything that's not an authorize URL if (!request.getServletPath().startsWith("/authorize")) { chain.doFilter(req, res); @@ -88,7 +87,7 @@ public class PromptFilter extends GenericFilterBean { AuthorizationRequest authRequest = authRequestFactory.createAuthorizationRequest(createRequestMap(request.getParameterMap())); ClientDetailsEntity client = null; - + try { client = clientService.loadClientByClientId(authRequest.getClientId()); } catch (InvalidClientException e) { @@ -96,7 +95,7 @@ public class PromptFilter extends GenericFilterBean { } catch (IllegalArgumentException e) { // no need to worry about this here, it would be caught elsewhere } - + if (authRequest.getExtensions().get("prompt") != null) { // we have a "prompt" parameter String prompt = (String)authRequest.getExtensions().get("prompt"); @@ -156,14 +155,14 @@ public class PromptFilter extends GenericFilterBean { Integer max = (client != null ? client.getDefaultMaxAge() : null); String maxAge = (String) authRequest.getExtensions().get("max_age"); if (maxAge != null) { - max = Integer.parseInt(maxAge); + max = Integer.parseInt(maxAge); } - + if (max != null) { - + HttpSession session = request.getSession(); Date authTime = (Date) session.getAttribute(AuthenticationTimeStamper.AUTH_TIMESTAMP); - + Date now = new Date(); if (authTime != null) { long seconds = (now.getTime() - authTime.getTime()) / 1000; 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 f14b1c806..e3825ef57 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 @@ -53,7 +53,7 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { @Autowired private OAuth2TokenRepository tokenRepository; - + @Autowired private StatsService statsService; @@ -90,7 +90,7 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { } approvedSiteRepository.remove(approvedSite); - + statsService.resetCache(); } @@ -164,7 +164,7 @@ public class DefaultApprovedSiteService implements ApprovedSiteService { remove(expired); } } - + } private Predicate isExpired = new Predicate() { diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java index c30ebaf2b..92f4c8e75 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java @@ -78,7 +78,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService { @Autowired private JWKSetCacheService encrypters; - + @Autowired private SymmetricCacheService symmetricCacheService; @@ -99,7 +99,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService { if (request.getExtensions().containsKey("max_age") || (request.getExtensions().containsKey("idtoken")) // TODO: parse the ID Token claims (#473) -- for now assume it could be in there || (client.getRequireAuthTime() != null && client.getRequireAuthTime())) { - + Date authTime = (Date) request.getExtensions().get(AuthenticationTimeStamper.AUTH_TIMESTAMP); if (authTime != null) { idClaims.setClaim("auth_time", authTime.getTime() / 1000); @@ -130,42 +130,42 @@ public class DefaultOIDCTokenService implements OIDCTokenService { Base64URL at_hash = IdTokenHashUtils.getAccessTokenHash(signingAlg, accessToken); idClaims.setClaim("at_hash", at_hash); } - + if (client.getIdTokenEncryptedResponseAlg() != null && !client.getIdTokenEncryptedResponseAlg().equals(Algorithm.NONE) && client.getIdTokenEncryptedResponseEnc() != null && !client.getIdTokenEncryptedResponseEnc().equals(Algorithm.NONE) && !Strings.isNullOrEmpty(client.getJwksUri())) { - + JwtEncryptionAndDecryptionService encrypter = encrypters.getEncrypter(client.getJwksUri()); - + if (encrypter != null) { - + EncryptedJWT idToken = new EncryptedJWT(new JWEHeader(client.getIdTokenEncryptedResponseAlg(), client.getIdTokenEncryptedResponseEnc()), idClaims); - + encrypter.encryptJwt(idToken); - + idTokenEntity.setJwt(idToken); - + } else { logger.error("Couldn't find encrypter for client: " + client.getClientId()); } - + } else { SignedJWT idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims); - + if (signingAlg.equals(JWSAlgorithm.HS256) || signingAlg.equals(JWSAlgorithm.HS384) || signingAlg.equals(JWSAlgorithm.HS512)) { JwtSigningAndValidationService signer = symmetricCacheService.getSymmetricValidtor(client); - + // sign it with the client's secret signer.signJwt(idToken); } else { - + // sign it with the server's key jwtService.signJwt(idToken); } - + idTokenEntity.setJwt(idToken); } 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 d9dcc3173..1cd6d15a7 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 @@ -51,37 +51,37 @@ public class DefaultStatsService implements StatsService { @Autowired private ClientDetailsEntityService clientService; - + // stats cache private Supplier> summaryCache = createSummaryCache(); - + private Supplier> createSummaryCache() { return Suppliers.memoizeWithExpiration(new Supplier>() { @Override public Map get() { return computeSummaryStats(); } - + }, 10, TimeUnit.MINUTES); } private Supplier> byClientIdCache = createByClientIdCache(); - + private Supplier> createByClientIdCache() { return Suppliers.memoizeWithExpiration(new Supplier>() { @Override public Map get() { return computeByClientId(); } - + }, 10, TimeUnit.MINUTES); } - + @Override public Map getSummaryStats() { return summaryCache.get(); } - + // do the actual computation private Map computeSummaryStats() { // get all approved sites @@ -110,7 +110,7 @@ public class DefaultStatsService implements StatsService { public Map getByClientId() { return byClientIdCache.get(); } - + private Map computeByClientId() { // get all approved sites Collection allSites = approvedSiteService.getAll(); @@ -162,5 +162,5 @@ public class DefaultStatsService implements StatsService { summaryCache = createSummaryCache(); byClientIdCache = createByClientIdCache(); } - + } 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 f0127438e..5ee4cde34 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 @@ -33,7 +33,6 @@ import org.mitre.openid.connect.service.UserInfoService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; @@ -41,7 +40,6 @@ import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.stereotype.Service; import com.google.common.collect.Lists; -import com.nimbusds.jose.Algorithm; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; import com.nimbusds.jwt.JWTClaimsSet; @@ -72,7 +70,7 @@ public class ConnectTokenEnhancer implements TokenEnhancer { @Autowired private JWKSetCacheService encryptors; - + @Autowired private SymmetricCacheService symmetricCacheService; @@ -105,7 +103,7 @@ public class ConnectTokenEnhancer implements TokenEnhancer { 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 @@ -115,18 +113,18 @@ public class ConnectTokenEnhancer implements TokenEnhancer { * Also, there must be a user authentication involved in the request for it to be considered * OIDC and not OAuth, so we check for that as well. */ - if (originalAuthRequest.getScope().contains("openid") + if (originalAuthRequest.getScope().contains("openid") && !authentication.isClientOnly()) { String username = authentication.getName(); UserInfo userInfo = userInfoService.getByUsernameAndClientId(username, clientId); if (userInfo != null) { - + OAuth2AccessTokenEntity idTokenEntity = connectTokenService.createIdToken(client, originalAuthRequest, claims.getIssueTime(), userInfo.getSub(), token); - + // attach the id token to the parent access token token.setIdToken(idTokenEntity); } else { 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 59239cf7d..0e84594d0 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 @@ -97,18 +97,18 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { } else { // if not, check to see if the user has approved it if (Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval"))) { // TODO: make parameter name configurable? - + // check the value of the CSRF parameter - + if (authorizationRequest.getExtensions().get("csrf") != null) { if (authorizationRequest.getExtensions().get("csrf").equals(authorizationRequest.getApprovalParameters().get("csrf"))) { - + // make sure the user is actually authenticated - return userAuthentication.isAuthenticated(); + return userAuthentication.isAuthenticated(); } } } - + // if the above doesn't pass, it's not yet approved return false; } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoJwtView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoJwtView.java index 11d2b1fc7..39319862c 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoJwtView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoJwtView.java @@ -9,7 +9,6 @@ import java.io.Writer; import java.text.ParseException; import java.util.Date; import java.util.Map; -import java.util.Map.Entry; import java.util.UUID; import javax.servlet.http.HttpServletRequest; @@ -28,7 +27,6 @@ import org.springframework.stereotype.Component; import com.google.common.base.Strings; import com.google.common.collect.Lists; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.nimbusds.jose.Algorithm; import com.nimbusds.jose.JWEHeader; @@ -46,16 +44,16 @@ import com.nimbusds.jwt.SignedJWT; public class UserInfoJwtView extends UserInfoView { private static Logger logger = LoggerFactory.getLogger(UserInfoJwtView.class); - + @Autowired private JwtSigningAndValidationService jwtService; - + @Autowired private ConfigurationPropertiesBean config; - + @Autowired private JWKSetCacheService encrypters; - + @Autowired private SymmetricCacheService symmetricCacheService; @@ -65,40 +63,40 @@ public class UserInfoJwtView extends UserInfoView { try { ClientDetailsEntity client = (ClientDetailsEntity)model.get("client"); - + // use the parser to import the user claims into the object StringWriter writer = new StringWriter(); gson.toJson(json, writer); - + JWTClaimsSet claims = JWTClaimsSet.parse(writer.toString()); - + claims.setAudience(Lists.newArrayList(client.getClientId())); - + claims.setIssuer(config.getIssuer()); - + claims.setIssueTime(new Date()); - + claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it - - + + if (client.getIdTokenEncryptedResponseAlg() != null && !client.getIdTokenEncryptedResponseAlg().equals(Algorithm.NONE) && client.getIdTokenEncryptedResponseEnc() != null && !client.getIdTokenEncryptedResponseEnc().equals(Algorithm.NONE) && !Strings.isNullOrEmpty(client.getJwksUri())) { // encrypt it to the client's key - + JwtEncryptionAndDecryptionService encrypter = encrypters.getEncrypter(client.getJwksUri()); - + if (encrypter != null) { - + EncryptedJWT encrypted = new EncryptedJWT(new JWEHeader(client.getIdTokenEncryptedResponseAlg(), client.getIdTokenEncryptedResponseEnc()), claims); - + encrypter.encryptJwt(encrypted); - - + + Writer out = response.getWriter(); out.write(encrypted.serialize()); - + } else { logger.error("Couldn't find encrypter for client: " + client.getClientId()); } @@ -108,9 +106,9 @@ public class UserInfoJwtView extends UserInfoView { if (client.getUserInfoSignedResponseAlg() != null) { signingAlg = client.getUserInfoSignedResponseAlg(); } - + SignedJWT signed = new SignedJWT(new JWSHeader(signingAlg), claims); - + if (signingAlg.equals(JWSAlgorithm.HS256) || signingAlg.equals(JWSAlgorithm.HS384) || signingAlg.equals(JWSAlgorithm.HS512)) { @@ -123,16 +121,16 @@ public class UserInfoJwtView extends UserInfoView { // sign it with the server's key jwtService.signJwt(signed); } - + Writer out = response.getWriter(); out.write(signed.serialize()); -} + } } catch (IOException e) { logger.error("IO Exception in UserInfoJwtView", e); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } - + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoView.java index 732f4652a..931153880 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoView.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/UserInfoView.java @@ -90,29 +90,29 @@ public class UserInfoView extends AbstractView { response.setContentType("application/json"); - JsonObject authorizedClaims = null; - JsonObject requestedClaims = null; - if (model.get("authorizedClaims") != null) { - authorizedClaims = jsonParser.parse((String) model.get("authorizedClaims")).getAsJsonObject(); - } - if (model.get("requestedClaims") != null) { - requestedClaims = jsonParser.parse((String) model.get("requestedClaims")).getAsJsonObject(); - } - JsonObject json = toJsonFromRequestObj(userInfo, scope, authorizedClaims, requestedClaims); + JsonObject authorizedClaims = null; + JsonObject requestedClaims = null; + if (model.get("authorizedClaims") != null) { + authorizedClaims = jsonParser.parse((String) model.get("authorizedClaims")).getAsJsonObject(); + } + if (model.get("requestedClaims") != null) { + requestedClaims = jsonParser.parse((String) model.get("requestedClaims")).getAsJsonObject(); + } + JsonObject json = toJsonFromRequestObj(userInfo, scope, authorizedClaims, requestedClaims); - writeOut(json, model, request, response); + writeOut(json, model, request, response); } - + protected void writeOut(JsonObject json, Map model, HttpServletRequest request, HttpServletResponse response) { try { Writer out = response.getWriter(); gson.toJson(json, out); } catch (IOException e) { - + logger.error("IOException in UserInfoView.java: ", e); - + } - + } /** 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 420cc0633..9110ca485 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 @@ -65,7 +65,7 @@ public class ClientDynamicRegistrationEndpoint { @Autowired private SystemScopeService scopeService; - + @Autowired private BlacklistedSiteService blacklistService; @@ -125,33 +125,33 @@ public class ClientDynamicRegistrationEndpoint { newClient.setGrantTypes(Sets.newHashSet("authorization_code")); // allow authorization code grant type by default } } - + // check to make sure this client registered a redirect URI if using a redirect flow if (newClient.getGrantTypes().contains("authorization_code") || newClient.getGrantTypes().contains("implicit")) { if (newClient.getRedirectUris() == null || newClient.getRedirectUris().isEmpty()) { // return an error - m.addAttribute("error", "invalid_client_uri"); + m.addAttribute("error", "invalid_client_uri"); m.addAttribute("errorMessage", "Clients using a redirect-based grant type must register at least one redirect URI."); m.addAttribute("code", HttpStatus.BAD_REQUEST); return "jsonErrorView"; } - + for (String uri : newClient.getRedirectUris()) { if (blacklistService.isBlacklisted(uri)) { // return an error - m.addAttribute("error", "invalid_client_uri"); + m.addAttribute("error", "invalid_client_uri"); m.addAttribute("errorMessage", "Redirect URI is not allowed: " + uri); m.addAttribute("code", HttpStatus.BAD_REQUEST); return "jsonErrorView"; - } + } } } - + // 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 } @@ -175,7 +175,7 @@ public class ClientDynamicRegistrationEndpoint { // this client has been dynamically registered (obviously) newClient.setDynamicallyRegistered(true); - + // this client can't do token introspection newClient.setAllowIntrospection(false); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java index 407b995cb..4a65a093c 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java @@ -65,7 +65,7 @@ public class ProtectedResourceRegistrationEndpoint { @Autowired private SystemScopeService scopeService; - + @Autowired private BlacklistedSiteService blacklistService; @@ -121,7 +121,7 @@ public class ProtectedResourceRegistrationEndpoint { newClient.setGrantTypes(new HashSet()); newClient.setResponseTypes(new HashSet()); newClient.setRedirectUris(new HashSet()); - + if (newClient.getTokenEndpointAuthMethod() == null) { newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC); } @@ -133,12 +133,12 @@ public class ProtectedResourceRegistrationEndpoint { // we need to generate a secret newClient = clientService.generateClientSecret(newClient); } - + // don't issue tokens to this client newClient.setAccessTokenValiditySeconds(0); newClient.setIdTokenValiditySeconds(0); newClient.setRefreshTokenValiditySeconds(0); - + // clear out unused fields newClient.setDefaultACRvalues(new HashSet()); newClient.setDefaultMaxAge(null); @@ -158,7 +158,7 @@ public class ProtectedResourceRegistrationEndpoint { // this client has been dynamically registered (obviously) newClient.setDynamicallyRegistered(true); - + // this client has access to the introspection endpoint newClient.setAllowIntrospection(true); 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 ca01a2d3a..977ba9601 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 @@ -31,7 +31,6 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,7 +49,7 @@ public class UserInfoEndpoint { @Autowired private UserInfoService userInfoService; - + @Autowired private ClientDetailsEntityService clientService; @@ -61,7 +60,7 @@ public class UserInfoEndpoint { */ @PreAuthorize("hasRole('ROLE_USER') and #oauth2.hasScope('openid')") @RequestMapping(value="/userinfo", method= {RequestMethod.GET, RequestMethod.POST}, produces = {"application/json", "application/jwt"}) - public String getInfo(@RequestParam(value="claims", required=false) String claimsRequestJsonString, + public String getInfo(@RequestParam(value="claims", required=false) String claimsRequestJsonString, @RequestHeader(value="Accept") String acceptHeader, OAuth2Authentication auth, Model model) { @@ -93,9 +92,9 @@ public class UserInfoEndpoint { // content negotiation List mediaTypes = MediaType.parseMediaTypes(acceptHeader); MediaType.sortBySpecificityAndQuality(mediaTypes); - + MediaType jose = new MediaType("application", "jwt"); - + for (MediaType m : mediaTypes) { if (!m.isWildcardType() && m.isCompatibleWith(jose)) { ClientDetailsEntity client = clientService.loadClientByClientId(auth.getOAuth2Request().getClientId()); @@ -104,8 +103,8 @@ public class UserInfoEndpoint { return "userInfoJwtView"; } } - - return "userInfoView"; + + return "userInfoView"; } diff --git a/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java b/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java index 0fb6dbe30..d99457170 100644 --- a/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java +++ b/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java @@ -68,7 +68,7 @@ public class TestDefaultOAuth2ClientDetailsEntityService { @Mock private SystemScopeService scopeService; - + @Mock private StatsService statsService; diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java index bf0de584d..d413b0d53 100644 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java +++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java @@ -51,7 +51,7 @@ public class TestDefaultApprovedSiteService { @Mock private ApprovedSiteRepository repository; - + @Mock private StatsService statsService; diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultStatsService.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultStatsService.java index 8e0338f53..8be625b54 100644 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultStatsService.java +++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultStatsService.java @@ -99,7 +99,7 @@ public class TestDefaultStatsService { Mockito.when(ap5.getUserId()).thenReturn(userId2); Mockito.when(ap5.getClientId()).thenReturn(clientId1); - + Mockito.when(ap6.getUserId()).thenReturn(userId1); Mockito.when(ap6.getClientId()).thenReturn(clientId4); @@ -170,10 +170,10 @@ public class TestDefaultStatsService { assertThat(service.getCountForClientId(3L), is(1)); assertThat(service.getCountForClientId(4L), is(0)); } - + @Test public void cacheAndReset() { - + Map stats = service.getSummaryStats(); assertThat(stats.get("approvalCount"), is(4)); @@ -181,22 +181,22 @@ public class TestDefaultStatsService { assertThat(stats.get("clientCount"), is(3)); Mockito.when(approvedSiteService.getAll()).thenReturn(Sets.newHashSet(ap1, ap2, ap3, ap4, ap5, ap6)); - + Map stats2 = service.getSummaryStats(); - + // cache should remain the same due to memoized functions assertThat(stats2.get("approvalCount"), is(4)); assertThat(stats2.get("userCount"), is(2)); - assertThat(stats2.get("clientCount"), is(3)); - + assertThat(stats2.get("clientCount"), is(3)); + // reset the cache and make sure the count goes up service.resetCache(); - + Map stats3 = service.getSummaryStats(); - + assertThat(stats3.get("approvalCount"), is(6)); assertThat(stats3.get("userCount"), is(2)); - assertThat(stats3.get("clientCount"), is(4)); - + assertThat(stats3.get("clientCount"), is(4)); + } }