1
0
mirror of synced 2026-08-04 09:17:02 +00:00

Use id_token for user authentication

Fixes gh-4410
This commit is contained in:
Joe Grandja
2017-06-27 11:45:19 -04:00
parent c986b6f4b5
commit 9cfb890207
43 changed files with 1328 additions and 583 deletions
@@ -35,6 +35,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationProcessingFilter;
import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken;
import org.springframework.security.oauth2.client.authentication.AuthorizationCodeRequestRedirectFilter;
@@ -48,6 +49,7 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2Parameter;
import org.springframework.security.oauth2.core.endpoint.ResponseType;
import org.springframework.security.oauth2.core.endpoint.TokenResponseAttributes;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
@@ -389,7 +391,11 @@ public class OAuth2LoginApplicationTests {
attributes.put("last-name", "Grandja");
attributes.put("email", "joeg@springsecurity.io");
DefaultOAuth2User user = new DefaultOAuth2User(attributes, "email");
GrantedAuthority authority = new OAuth2UserAuthority(attributes);
Set<GrantedAuthority> authorities = new HashSet<>();
authorities.add(authority);
DefaultOAuth2User user = new DefaultOAuth2User(authorities, attributes, "email");
OAuth2UserService mock = mock(OAuth2UserService.class);
when(mock.loadUser(any())).thenReturn(user);
@@ -24,21 +24,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.user.converter.AbstractOAuth2UserConverter;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.Set;
import java.util.function.Function;
import static org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration.*;
@@ -54,8 +48,7 @@ import static org.springframework.boot.autoconfigure.security.oauth2.client.Clie
@AutoConfigureAfter(ClientRegistrationAutoConfiguration.class)
public class OAuth2LoginAutoConfiguration {
private static final String USER_INFO_URI_PROPERTY = "user-info-uri";
private static final String USER_INFO_CONVERTER_PROPERTY = "user-info-converter";
private static final String USER_INFO_NAME_ATTR_KEY_PROPERTY = "user-info-name-attribute-key";
private static final String USER_NAME_ATTR_NAME_PROPERTY = "user-name-attribute-name";
@EnableWebSecurity
protected static class OAuth2LoginSecurityConfiguration extends WebSecurityConfigurerAdapter {
@@ -75,11 +68,11 @@ public class OAuth2LoginAutoConfiguration {
.and()
.oauth2Login();
this.registerUserInfoTypeConverters(http.oauth2Login());
this.registerUserNameAttributeNames(http.oauth2Login());
}
// @formatter:on
private void registerUserInfoTypeConverters(OAuth2LoginConfigurer<HttpSecurity> oauth2LoginConfigurer) throws Exception {
private void registerUserNameAttributeNames(OAuth2LoginConfigurer<HttpSecurity> oauth2LoginConfigurer) throws Exception {
Set<String> clientPropertyKeys = resolveClientPropertyKeys(this.environment);
for (String clientPropertyKey : clientPropertyKeys) {
String fullClientPropertyKey = CLIENT_PROPERTY_PREFIX + "." + clientPropertyKey;
@@ -87,22 +80,9 @@ public class OAuth2LoginAutoConfiguration {
continue;
}
String userInfoUriValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_URI_PROPERTY);
String userInfoConverterTypeValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_CONVERTER_PROPERTY);
if (userInfoUriValue != null && userInfoConverterTypeValue != null) {
Class<? extends Function> userInfoConverterType = ClassUtils.resolveClassName(
userInfoConverterTypeValue, this.getClass().getClassLoader()).asSubclass(Function.class);
Function<ClientHttpResponse, ? extends OAuth2User> userInfoConverter = null;
if (AbstractOAuth2UserConverter.class.isAssignableFrom(userInfoConverterType)) {
Constructor<? extends Function> oauth2UserConverterConstructor = ClassUtils.getConstructorIfAvailable(userInfoConverterType, String.class);
if (oauth2UserConverterConstructor != null) {
String userInfoNameAttributeKey = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_NAME_ATTR_KEY_PROPERTY);
userInfoConverter = (Function<ClientHttpResponse, ? extends OAuth2User>)oauth2UserConverterConstructor.newInstance(userInfoNameAttributeKey);
}
}
if (userInfoConverter == null) {
userInfoConverter = (Function<ClientHttpResponse, ? extends OAuth2User>)userInfoConverterType.newInstance();
}
oauth2LoginConfigurer.userInfoEndpoint().userInfoTypeConverter(userInfoConverter, new URI(userInfoUriValue));
String userNameAttributeNameValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_NAME_ATTR_NAME_PROPERTY);
if (userInfoUriValue != null && userNameAttributeNameValue != null) {
oauth2LoginConfigurer.userInfoEndpoint().userNameAttributeName(userNameAttributeNameValue, URI.create(userInfoUriValue));
}
}
}
@@ -16,17 +16,19 @@
package sample.user;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.core.user.OAuth2User;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Joe Grandja
*/
public class GitHubOAuth2User implements OAuth2User {
private List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
private String id;
private String name;
private String login;
@@ -37,7 +39,7 @@ public class GitHubOAuth2User implements OAuth2User {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.emptyList();
return this.authorities;
}
@Override
@@ -9,7 +9,7 @@ security:
authorization-uri: "https://accounts.google.com/o/oauth2/auth"
token-uri: "https://accounts.google.com/o/oauth2/token"
user-info-uri: "https://www.googleapis.com/oauth2/v3/userinfo"
user-info-converter: "org.springframework.security.oauth2.client.user.converter.UserInfoConverter"
jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs
client-name: Google
client-alias: google
github:
@@ -20,7 +20,6 @@ security:
authorization-uri: "https://github.com/login/oauth/authorize"
token-uri: "https://github.com/login/oauth/access_token"
user-info-uri: "https://api.github.com/user"
user-info-converter: "org.springframework.security.oauth2.client.user.converter.OAuth2UserConverter"
client-name: GitHub
client-alias: github
facebook:
@@ -31,7 +30,6 @@ security:
authorization-uri: "https://www.facebook.com/v2.8/dialog/oauth"
token-uri: "https://graph.facebook.com/v2.8/oauth/access_token"
user-info-uri: "https://graph.facebook.com/me"
user-info-converter: "org.springframework.security.oauth2.client.user.converter.OAuth2UserConverter"
client-name: Facebook
client-alias: facebook
okta:
@@ -39,6 +37,5 @@ security:
authorized-grant-type: authorization_code
redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{clientAlias}"
scopes: openid, email, profile
user-info-converter: "org.springframework.security.oauth2.client.user.converter.UserInfoConverter"
client-name: Okta
client-alias: okta
@@ -21,14 +21,15 @@ security:
github:
client-id: your-app-client-id
client-secret: your-app-client-secret
user-info-name-attribute-key: "name"
user-name-attribute-name: "name"
facebook:
client-id: your-app-client-id
client-secret: your-app-client-secret
user-info-name-attribute-key: "name"
user-name-attribute-name: "name"
okta:
client-id: your-app-client-id
client-secret: your-app-client-secret
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys