Spring Security OAuth2.0笔记

请求命中filter:
spring-security-oauth2-client:5.3.5.RELEASE
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter
@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		try {
			OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);
			if (authorizationRequest != null) {
				this.sendRedirectForAuthorization(request, response, authorizationRequest);
				return;
			}
		} catch (Exception failed) {
			this.unsuccessfulRedirectForAuthorization(request, response, failed);
			return;
		}
org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver
	private String resolveRegistrationId(HttpServletRequest request) {
		if (this.authorizationRequestMatcher.matches(request)) {
			return this.authorizationRequestMatcher
					.matcher(request).getVariables().get(REGISTRATION_ID_URI_VARIABLE_NAME);
		}
		return null;
	}
	@Override
	public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
		String registrationId = this.resolveRegistrationId(request);
		String redirectUriAction = getAction(request, "login");
		return resolve(request, registrationId, redirectUriAction);
	}

默认的redirectUriAction="login"

 

开始解析出OAuth2AuthorizationRequest对象

private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId, String redirectUriAction) {
		if (registrationId == null) {
			return null;
		}

		ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
		if (clientRegistration == null) {
			throw new IllegalArgumentException("Invalid Client Registration with Id: " + registrationId);
		}

		Map<String, Object> attributes = new HashMap<>();
		attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());

		OAuth2AuthorizationRequest.Builder builder;
		if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) {
			builder = OAuth2AuthorizationRequest.authorizationCode();
			Map<String, Object> additionalParameters = new HashMap<>();
			if (!CollectionUtils.isEmpty(clientRegistration.getScopes()) &&
					clientRegistration.getScopes().contains(OidcScopes.OPENID)) {
				// Section 3.1.2.1 Authentication Request - https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
				// scope
				// 		REQUIRED. OpenID Connect requests MUST contain the "openid" scope value.
				addNonceParameters(attributes, additionalParameters);
			}
			if (ClientAuthenticationMethod.NONE.equals(clientRegistration.getClientAuthenticationMethod())) {
				addPkceParameters(attributes, additionalParameters);
			}
			builder.additionalParameters(additionalParameters);
		} else if (AuthorizationGrantType.IMPLICIT.equals(clientRegistration.getAuthorizationGrantType())) {
			builder = OAuth2AuthorizationRequest.implicit();
		} else {
			throw new IllegalArgumentException("Invalid Authorization Grant Type ("  +
					clientRegistration.getAuthorizationGrantType().getValue() +
					") for Client Registration with Id: " + clientRegistration.getRegistrationId());
		}

		String redirectUriStr = expandRedirectUri(request, clientRegistration, redirectUriAction);

		builder
				.clientId(clientRegistration.getClientId())
				.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
				.redirectUri(redirectUriStr)
				.scopes(clientRegistration.getScopes())
				.state(this.stateGenerator.generateKey())
				.attributes(attributes);

		this.authorizationRequestCustomizer.accept(builder);

		return builder.build();
	}

 

GrantType

public final class AuthorizationGrantType implements Serializable {
    private static final long serialVersionUID = 530L;
    public static final AuthorizationGrantType AUTHORIZATION_CODE = new AuthorizationGrantType("authorization_code");
    /** @deprecated */
    @Deprecated
    public static final AuthorizationGrantType IMPLICIT = new AuthorizationGrantType("implicit");
    public static final AuthorizationGrantType REFRESH_TOKEN = new AuthorizationGrantType("refresh_token");
    public static final AuthorizationGrantType CLIENT_CREDENTIALS = new AuthorizationGrantType("client_credentials");
    public static final AuthorizationGrantType PASSWORD = new AuthorizationGrantType("password");

 

spring-security-oauth2-client:5.3.5.RELEASE

org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter

public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
	/**
	 * The default {@code URI} where this {@code Filter} processes authentication requests.
	 */
	public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/oauth2/code/*";
	private static final String AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE = "authorization_request_not_found";
	private static final String CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE = "client_registration_not_found";
	private ClientRegistrationRepository clientRegistrationRepository;
	private OAuth2AuthorizedClientRepository authorizedClientRepository;
	private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =
		new HttpSessionOAuth2AuthorizationRequestRepository();

 

源码:

spring-security-config:5.3.5.RELEASE
org.springframework.security.config.http.OAuth2LoginBeanDefinitionParser
final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {

	private static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization";
	private static final String DEFAULT_LOGIN_URI = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL;

	private static final String ELT_CLIENT_REGISTRATION = "client-registration";
	private static final String ATT_REGISTRATION_ID = "registration-id";
	private static final String ATT_CLIENT_REGISTRATION_REPOSITORY_REF = "client-registration-repository-ref";
	private static final String ATT_AUTHORIZED_CLIENT_REPOSITORY_REF = "authorized-client-repository-ref";
	private static final String ATT_AUTHORIZED_CLIENT_SERVICE_REF = "authorized-client-service-ref";
	private static final String ATT_AUTHORIZATION_REQUEST_REPOSITORY_REF = "authorization-request-repository-ref";
	private static final String ATT_AUTHORIZATION_REQUEST_RESOLVER_REF = "authorization-request-resolver-ref";
	private static final String ATT_ACCESS_TOKEN_RESPONSE_CLIENT_REF = "access-token-response-client-ref";
	private static final String ATT_USER_AUTHORITIES_MAPPER_REF = "user-authorities-mapper-ref";
	private static final String ATT_USER_SERVICE_REF = "user-service-ref";
	private static final String ATT_OIDC_USER_SERVICE_REF = "oidc-user-service-ref";
	private static final String ATT_LOGIN_PROCESSING_URL = "login-processing-url";
	private static final String ATT_LOGIN_PAGE = "login-page";
	private static final String ATT_AUTHENTICATION_SUCCESS_HANDLER_REF = "authentication-success-handler-ref";
	private static final String ATT_AUTHENTICATION_FAILURE_HANDLER_REF = "authentication-failure-handler-ref";
	private static final String ATT_JWT_DECODER_FACTORY_REF = "jwt-decoder-factory-ref";

 

public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		Class<? extends Authentication> toTest = authentication.getClass();
		AuthenticationException lastException = null;
		AuthenticationException parentException = null;
		Authentication result = null;
		Authentication parentResult = null;
		boolean debug = logger.isDebugEnabled();

		for (AuthenticationProvider provider : getProviders()) {
			if (!provider.supports(toTest)) {
				continue;
			}

			if (debug) {
				logger.debug("Authentication attempt using "
						+ provider.getClass().getName());
			}

 

 

@Override
	public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
		Assert.notNull(userRequest, "userRequest cannot be null");

		if (!StringUtils.hasText(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())) {
			OAuth2Error oauth2Error = new OAuth2Error(
				MISSING_USER_INFO_URI_ERROR_CODE,
				"Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: " +
					userRequest.getClientRegistration().getRegistrationId(),
				null
			);
			throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
		}
		String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails()
				.getUserInfoEndpoint().getUserNameAttributeName();
		if (!StringUtils.hasText(userNameAttributeName)) {
			OAuth2Error oauth2Error = new OAuth2Error(
				MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE,
				"Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: " +
					userRequest.getClientRegistration().getRegistrationId(),
				null
			);
			throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
		}

		RequestEntity<?> request = this.requestEntityConverter.convert(userRequest);

		ResponseEntity<Map<String, Object>> response;
		try {
			response = this.restOperations.exchange(request, PARAMETERIZED_RESPONSE_TYPE);
		} catch (OAuth2AuthorizationException ex) {

 

 

https://docs.spring.io/spring-security/site/docs/5.3.5.RELEASE/reference/html5/#oauth2login-boot-property-mappings

12.1.2. Spring Boot 2.x Property Mappings

The following table outlines the mapping of the Spring Boot 2.x OAuth Client properties to the ClientRegistration properties.

Spring Boot 2.xClientRegistration

spring.security.oauth2.client.registration.[registrationId]

registrationId

spring.security.oauth2.client.registration.[registrationId].client-id

clientId

spring.security.oauth2.client.registration.[registrationId].client-secret

clientSecret

spring.security.oauth2.client.registration.[registrationId].client-authentication-method

clientAuthenticationMethod

spring.security.oauth2.client.registration.[registrationId].authorization-grant-type

authorizationGrantType

spring.security.oauth2.client.registration.[registrationId].redirect-uri

redirectUriTemplate

spring.security.oauth2.client.registration.[registrationId].scope

scopes

spring.security.oauth2.client.registration.[registrationId].client-name

clientName

spring.security.oauth2.client.provider.[providerId].authorization-uri

providerDetails.authorizationUri

spring.security.oauth2.client.provider.[providerId].token-uri

providerDetails.tokenUri

spring.security.oauth2.client.provider.[providerId].jwk-set-uri

providerDetails.jwkSetUri

spring.security.oauth2.client.provider.[providerId].user-info-uri

providerDetails.userInfoEndpoint.uri

spring.security.oauth2.client.provider.[providerId].user-info-authentication-method

providerDetails.userInfoEndpoint.authenticationMethod

spring.security.oauth2.client.provider.[providerId].user-name-attribute

providerDetails.userInfoEndpoint.userNameAttributeName

 

https://docs.spring.io/spring-security/site/docs/5.3.5.RELEASE/reference/html5/#oauth2login-register-clientregistrationrepository-bean

@Configuration
public class OAuth2LoginConfig {

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
    }

    private ClientRegistration googleClientRegistration() {
        return ClientRegistration.withRegistrationId("google")
            .clientId("google-client-id")
            .clientSecret("google-client-secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
            .scope("openid", "profile", "email", "address", "phone")
            .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
            .tokenUri("https://www.googleapis.com/oauth2/v4/token")
            .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
            .userNameAttributeName(IdTokenClaimNames.SUB)
            .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
            .clientName("Google")
            .build();
    }
}
public interface StandardClaimNames {

	/**
	 * {@code sub} - the Subject identifier
	 */
	String SUB = "sub";

	/**
	 * {@code name} - the user's full name
	 */
	String NAME = "name";

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页