Fix CNF exception if oauth2-jose dependency not included

Fixes gh-4753
This commit is contained in:
Joe Grandja 2017-11-12 12:27:18 -05:00
parent 6775d9fdd8
commit aa9e057ba8
1 changed files with 56 additions and 11 deletions

View File

@ -18,12 +18,16 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.cl
import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider; import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider;
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
import org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
@ -40,13 +44,17 @@ import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter; import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -246,19 +254,25 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
} }
http.authenticationProvider(this.postProcess(oauth2LoginAuthenticationProvider)); http.authenticationProvider(this.postProcess(oauth2LoginAuthenticationProvider));
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = this.userInfoEndpointConfig.oidcUserService; boolean oidcAuthenticationProviderEnabled = ClassUtils.isPresent(
if (oidcUserService == null) { "org.springframework.security.oauth2.jwt.JwtDecoder", this.getClass().getClassLoader());
oidcUserService = new OidcUserService();
}
OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenticationProvider = if (oidcAuthenticationProviderEnabled) {
new OidcAuthorizationCodeAuthenticationProvider( OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = this.userInfoEndpointConfig.oidcUserService;
accessTokenResponseClient, oidcUserService); if (oidcUserService == null) {
if (this.userInfoEndpointConfig.userAuthoritiesMapper != null) { oidcUserService = new OidcUserService();
oidcAuthorizationCodeAuthenticationProvider.setAuthoritiesMapper( }
this.userInfoEndpointConfig.userAuthoritiesMapper);
OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenticationProvider =
new OidcAuthorizationCodeAuthenticationProvider(accessTokenResponseClient, oidcUserService);
if (this.userInfoEndpointConfig.userAuthoritiesMapper != null) {
oidcAuthorizationCodeAuthenticationProvider.setAuthoritiesMapper(
this.userInfoEndpointConfig.userAuthoritiesMapper);
}
http.authenticationProvider(this.postProcess(oidcAuthorizationCodeAuthenticationProvider));
} else {
http.authenticationProvider(new OidcAuthenticationRequestChecker());
} }
http.authenticationProvider(this.postProcess(oidcAuthorizationCodeAuthenticationProvider));
this.initDefaultLoginFilter(http); this.initDefaultLoginFilter(http);
} }
@ -359,4 +373,35 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage()); loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage());
loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl()); loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl());
} }
private static class OidcAuthenticationRequestChecker implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OAuth2LoginAuthenticationToken authorizationCodeAuthentication =
(OAuth2LoginAuthenticationToken) authentication;
// Section 3.1.2.1 Authentication Request - http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
// scope
// REQUIRED. OpenID Connect requests MUST contain the "openid" scope value.
if (authorizationCodeAuthentication.getAuthorizationExchange()
.getAuthorizationRequest().getScopes().contains(OidcScopes.OPENID)) {
OAuth2Error oauth2Error = new OAuth2Error(
"oidc_provider_not_configured",
"An OpenID Connect Authentication Provider has not been configured. " +
"Check to ensure you include the dependency 'spring-security-oauth2-jose'.",
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return OAuth2LoginAuthenticationToken.class.isAssignableFrom(authentication);
}
}
} }