spring authorization server使用说明
相关依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 授权客户端 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency><!-- 授权服务器 --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-authorization-server</artifactId><version>0.3.1</version></dependency>
授权组件注册
OAuth2AuthorizationServerConfigurer:注册授权组件
public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBuilder<B>> extends AbstractHttpConfigurer<OAuth2AuthorizationServerConfigurer<B>, B> {private final Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> configurers = this.createConfigurers();private RequestMatcher jwkSetEndpointMatcher;private RequestMatcher authorizationServerMetadataEndpointMatcher;private final RequestMatcher endpointsMatcher = (request) -> {return this.getRequestMatcher(OAuth2AuthorizationEndpointConfigurer.class).matches(request) || this.getRequestMatcher(OAuth2TokenEndpointConfigurer.class).matches(request) || this.getRequestMatcher(OAuth2TokenIntrospectionEndpointConfigurer.class).matches(request) || this.getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class).matches(request) || this.getRequestMatcher(OidcConfigurer.class).matches(request) || this.jwkSetEndpointMatcher.matches(request) || this.authorizationServerMetadataEndpointMatcher.matches(request);};public OAuth2AuthorizationServerConfigurer() {}public OAuth2AuthorizationServerConfigurer<B> registeredClientRepository(RegisteredClientRepository registeredClientRepository) {public OAuth2AuthorizationServerConfigurer<B> authorizationService(OAuth2AuthorizationService authorizationService) {public OAuth2AuthorizationServerConfigurer<B> authorizationConsentService(OAuth2AuthorizationConsentService authorizationConsentService) {public OAuth2AuthorizationServerConfigurer<B> tokenGenerator(OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator) {public OAuth2AuthorizationServerConfigurer<B> providerSettings(ProviderSettings providerSettings) {public OAuth2AuthorizationServerConfigurer<B> clientAuthentication(Customizer<OAuth2ClientAuthenticationConfigurer> clientAuthenticationCustomizer) {public OAuth2AuthorizationServerConfigurer<B> authorizationEndpoint(Customizer<OAuth2AuthorizationEndpointConfigurer> authorizationEndpointCustomizer) {public OAuth2AuthorizationServerConfigurer<B> tokenEndpoint(Customizer<OAuth2TokenEndpointConfigurer> tokenEndpointCustomizer) {public OAuth2AuthorizationServerConfigurer<B> tokenIntrospectionEndpoint(Customizer<OAuth2TokenIntrospectionEndpointConfigurer> tokenIntrospectionEndpointCustomizer) {public OAuth2AuthorizationServerConfigurer<B> tokenRevocationEndpoint(Customizer<OAuth2TokenRevocationEndpointConfigurer> tokenRevocationEndpointCustomizer) {public OAuth2AuthorizationServerConfigurer<B> oidc(Customizer<OidcConfigurer> oidcCustomizer) {public void init(B builder) {public void configure(B builder) {public RequestMatcher getEndpointsMatcher() {private <T> T getConfigurer(Class<T> type) {private void initEndpointMatchers(ProviderSettings providerSettings) {private static void validateProviderSettings(ProviderSettings providerSettings) {private <T extends AbstractOAuth2Configurer> RequestMatcher getRequestMatcher(Class<T> configurerType) {private Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> createConfigurers() {
客户端信息
RegisteredClient
public class RegisteredClient implements Serializable {private static final long serialVersionUID;private String id;private String clientId;private Instant clientIdIssuedAt;private String clientSecret;private Instant clientSecretExpiresAt;private String clientName;private Set<ClientAuthenticationMethod> clientAuthenticationMethods;private Set<AuthorizationGrantType> authorizationGrantTypes;private Set<String> redirectUris;private Set<String> scopes;private ClientSettings clientSettings;private TokenSettings tokenSettings;protected RegisteredClient() {}public String getId() {public String getClientId() {public String getClientName() {public Set<String> getScopes() {public Set<String> getRedirectUris() {public TokenSettings getTokenSettings() {public ClientSettings getClientSettings() {@Nullablepublic Instant getClientIdIssuedAt() {@Nullablepublic String getClientSecret() {@Nullablepublic Instant getClientSecretExpiresAt() {public Set<AuthorizationGrantType> getAuthorizationGrantTypes() {public Set<ClientAuthenticationMethod> getClientAuthenticationMethods() {public boolean equals(Object obj) {public int hashCode() {public String toString() {public static RegisteredClient.Builder withId(String id) { //创建构造类Assert.hasText(id, "id cannot be empty");return new RegisteredClient.Builder(id);}public static RegisteredClient.Builder from(RegisteredClient registeredClient) {Assert.notNull(registeredClient, "registeredClient cannot be null");return new RegisteredClient.Builder(registeredClient);}static {serialVersionUID = Version.SERIAL_VERSION_UID;}**********
Builder:客户端构造类public static class Builder implements Serializable {private static final long serialVersionUID;private String id;private String clientId;private Instant clientIdIssuedAt;private String clientSecret;private Instant clientSecretExpiresAt;private String clientName;private final Set<ClientAuthenticationMethod> clientAuthenticationMethods = new HashSet();private final Set<AuthorizationGrantType> authorizationGrantTypes = new HashSet();private final Set<String> redirectUris = new HashSet();private final Set<String> scopes = new HashSet();private ClientSettings clientSettings;private TokenSettings tokenSettings;protected Builder(String id) {protected Builder(RegisteredClient registeredClient) {public RegisteredClient.Builder id(String id) {public RegisteredClient.Builder clientId(String clientId) {public RegisteredClient.Builder clientName(String clientName) {public RegisteredClient.Builder clientSecret(String clientSecret) {public RegisteredClient.Builder clientIdIssuedAt(Instant clientIdIssuedAt) {public RegisteredClient.Builder clientSecretExpiresAt(Instant clientSecretExpiresAt) {public RegisteredClient.Builder clientAuthenticationMethod(ClientAuthenticationMethod clientAuthenticationMethod) {public RegisteredClient.Builder clientAuthenticationMethods(Consumer<Set<ClientAuthenticationMethod>> clientAuthenticationMethodsConsumer) {public RegisteredClient.Builder authorizationGrantType(AuthorizationGrantType authorizationGrantType) {public RegisteredClient.Builder authorizationGrantTypes(Consumer<Set<AuthorizationGrantType>> authorizationGrantTypesConsumer) {public RegisteredClient.Builder redirectUri(String redirectUri) {public RegisteredClient.Builder redirectUris(Consumer<Set<String>> redirectUrisConsumer) {public RegisteredClient.Builder scope(String scope) {public RegisteredClient.Builder scopes(Consumer<Set<String>> scopesConsumer) {public RegisteredClient.Builder clientSettings(ClientSettings clientSettings) {public RegisteredClient.Builder tokenSettings(TokenSettings tokenSettings) {public RegisteredClient build() {private void validateScopes() {private RegisteredClient create() {private void validateRedirectUris() {private boolean isPublicClientType() {private static boolean validateScope(String scope) {private static boolean validateRedirectUri(String redirectUri) {private static boolean withinTheRangeOf(int c, int min, int max) {static {serialVersionUID = Version.SERIAL_VERSION_UID;}
RegisteredClientRepository
public interface RegisteredClientRepository {void save(RegisteredClient registeredClient);@NullableRegisteredClient findById(String id);@NullableRegisteredClient findByClientId(String clientId);
}
InMemoryRegisteredClientRepository:内存中存储客户端信息
public final class InMemoryRegisteredClientRepository implements RegisteredClientRepository {private final Map<String, RegisteredClient> idRegistrationMap; //key为idprivate final Map<String, RegisteredClient> clientIdRegistrationMap; //key为clientIdpublic InMemoryRegisteredClientRepository(RegisteredClient... registrations) {this(Arrays.asList(registrations));}public InMemoryRegisteredClientRepository(List<RegisteredClient> registrations) {Assert.notEmpty(registrations, "registrations cannot be empty");ConcurrentHashMap<String, RegisteredClient> idRegistrationMapResult = new ConcurrentHashMap();ConcurrentHashMap<String, RegisteredClient> clientIdRegistrationMapResult = new ConcurrentHashMap();Iterator var4 = registrations.iterator();while(var4.hasNext()) {RegisteredClient registration = (RegisteredClient)var4.next();Assert.notNull(registration, "registration cannot be null");this.assertUniqueIdentifiers(registration, idRegistrationMapResult);idRegistrationMapResult.put(registration.getId(), registration);clientIdRegistrationMapResult.put(registration.getClientId(), registration);}this.idRegistrationMap = idRegistrationMapResult;this.clientIdRegistrationMap = clientIdRegistrationMapResult;}public void save(RegisteredClient registeredClient) {Assert.notNull(registeredClient, "registeredClient cannot be null");this.assertUniqueIdentifiers(registeredClient, this.idRegistrationMap);this.idRegistrationMap.put(registeredClient.getId(), registeredClient);this.clientIdRegistrationMap.put(registeredClient.getClientId(), registeredClient);}@Nullablepublic RegisteredClient findById(String id) {Assert.hasText(id, "id cannot be empty");return (RegisteredClient)this.idRegistrationMap.get(id);}@Nullablepublic RegisteredClient findByClientId(String clientId) {Assert.hasText(clientId, "clientId cannot be empty");return (RegisteredClient)this.clientIdRegistrationMap.get(clientId);}private void assertUniqueIdentifiers(RegisteredClient registeredClient, Map<String, RegisteredClient> registrations) {registrations.values().forEach((registration) -> {if (registeredClient.getId().equals(registration.getId())) {throw new IllegalArgumentException("Registered client must be unique. Found duplicate identifier: " + registeredClient.getId());} else if (registeredClient.getClientId().equals(registration.getClientId())) {throw new IllegalArgumentException("Registered client must be unique. Found duplicate client identifier: " + registeredClient.getClientId());} else if (StringUtils.hasText(registeredClient.getClientSecret()) && registeredClient.getClientSecret().equals(registration.getClientSecret())) {throw new IllegalArgumentException("Registered client must be unique. Found duplicate client secret for identifier: " + registeredClient.getId());}});}
}
JdbcRegisteredClientRepository:数据库中存储客户端信息,需要先建好表
public class JdbcRegisteredClientRepository implements RegisteredClientRepository {private static final String COLUMN_NAMES = "id, client_id, client_id_issued_at, client_secret, client_secret_expires_at, client_name, client_authentication_methods, authorization_grant_types, redirect_uris, scopes, client_settings,token_settings";private static final String TABLE_NAME = "oauth2_registered_client";private static final String PK_FILTER = "id = ?";private static final String LOAD_REGISTERED_CLIENT_SQL = "SELECT id, client_id, client_id_issued_at, client_secret, client_secret_expires_at, client_name, client_authentication_methods, authorization_grant_types, redirect_uris, scopes, client_settings,token_settings FROM oauth2_registered_client WHERE ";private static final String INSERT_REGISTERED_CLIENT_SQL = "INSERT INTO oauth2_registered_client(id, client_id, client_id_issued_at, client_secret, client_secret_expires_at, client_name, client_authentication_methods, authorization_grant_types, redirect_uris, scopes, client_settings,token_settings) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";private static final String UPDATE_REGISTERED_CLIENT_SQL = "UPDATE oauth2_registered_client SET client_name = ?, client_authentication_methods = ?, authorization_grant_types = ?, redirect_uris = ?, scopes = ?, client_settings = ?, token_settings = ? WHERE id = ?";private final JdbcOperations jdbcOperations;private RowMapper<RegisteredClient> registeredClientRowMapper;private Function<RegisteredClient, List<SqlParameterValue>> registeredClientParametersMapper;public JdbcRegisteredClientRepository(JdbcOperations jdbcOperations) {public RegisteredClient findById(String id) {public RegisteredClient findByClientId(String clientId) {public void save(RegisteredClient registeredClient) {public final void setRegisteredClientRowMapper(RowMapper<RegisteredClient> registeredClientRowMapper) {public final void setRegisteredClientParametersMapper(Function<RegisteredClient, List<SqlParameterValue>> registeredClientParametersMapper) {protected final JdbcOperations getJdbcOperations() {protected final RowMapper<RegisteredClient> getRegisteredClientRowMapper() {protected final Function<RegisteredClient, List<SqlParameterValue>> getRegisteredClientParametersMapper() {private RegisteredClient findBy(String filter, Object... args) {private void updateRegisteredClient(RegisteredClient registeredClient) {private void insertRegisteredClient(RegisteredClient registeredClient) {**********
静态内部类:RegisteredClientParametersMapperpublic static class RegisteredClientParametersMapper implements Function<RegisteredClient, List<SqlParameterValue>> {private ObjectMapper objectMapper = new ObjectMapper();public RegisteredClientParametersMapper() {public final void setObjectMapper(ObjectMapper objectMapper) {public List<SqlParameterValue> apply(RegisteredClient registeredClient) {protected final ObjectMapper getObjectMapper() {private String writeMap(Map<String, Object> data) {**********
静态内部类:RegisteredClientRowMapperpublic static class RegisteredClientRowMapper implements RowMapper<RegisteredClient> {private ObjectMapper objectMapper = new ObjectMapper();public RegisteredClientRowMapper() {public RegisteredClient mapRow(ResultSet rs, int rowNum) throws SQLException {public final void setObjectMapper(ObjectMapper objectMapper) {protected final ObjectMapper getObjectMapper() {private Map<String, Object> parseMap(String data) {private static AuthorizationGrantType resolveAuthorizationGrantType(String authorizationGrantType) {private static ClientAuthenticationMethod resolveClientAuthenticationMethod(String clientAuthenticationMethod) {
token 生成器
OAuth2TokenGenerator
@FunctionalInterface
public interface OAuth2TokenGenerator<T extends OAuth2Token> {@NullableT generate(OAuth2TokenContext context);
}
JwtGenerator
public final class JwtGenerator implements OAuth2TokenGenerator<Jwt> {private final JwtEncoder jwtEncoder;private OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer;public JwtGenerator(JwtEncoder jwtEncoder) {Assert.notNull(jwtEncoder, "jwtEncoder cannot be null");this.jwtEncoder = jwtEncoder;}@Nullablepublic Jwt generate(OAuth2TokenContext context) {public void setJwtCustomizer(OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer) {
、
DelegatingOAuth2TokenGenerator:组合生成器
public final class DelegatingOAuth2TokenGenerator implements OAuth2TokenGenerator<OAuth2Token> {private final List<OAuth2TokenGenerator<OAuth2Token>> tokenGenerators;@SafeVarargspublic DelegatingOAuth2TokenGenerator(OAuth2TokenGenerator<? extends OAuth2Token>... tokenGenerators) {Assert.notEmpty(tokenGenerators, "tokenGenerators cannot be empty");Assert.noNullElements(tokenGenerators, "tokenGenerator cannot be null");this.tokenGenerators = Collections.unmodifiableList(asList(tokenGenerators));}@Nullablepublic OAuth2Token generate(OAuth2TokenContext context) {Iterator var2 = this.tokenGenerators.iterator();OAuth2Token token;do {if (!var2.hasNext()) {return null;}OAuth2TokenGenerator<OAuth2Token> tokenGenerator = (OAuth2TokenGenerator)var2.next();token = tokenGenerator.generate(context);} while(token == null);return token;}private static List<OAuth2TokenGenerator<OAuth2Token>> asList(OAuth2TokenGenerator<? extends OAuth2Token>... tokenGenerators) {
OAuth2TokenCustomizer:自定义token格式
@FunctionalInterface
public interface OAuth2TokenCustomizer<T extends OAuth2TokenContext> {void customize(T context);
}
token 存储
OAuth2Authorization
public class OAuth2Authorization implements Serializable {private static final long serialVersionUID;public static final String AUTHORIZED_SCOPE_ATTRIBUTE_NAME;private String id; //OAuth2Authorization idprivate String registeredClientId; //客户端idprivate String principalName; //用户名称private AuthorizationGrantType authorizationGrantType; //授权类型private Map<Class<? extends OAuth2Token>, OAuth2Authorization.Token<?>> tokens;//授权tokenprivate Map<String, Object> attributes; //属性(scopes等)protected OAuth2Authorization() {}public String getId() {public String getPrincipalName() {public String getRegisteredClientId() {public Map<String, Object> getAttributes() {public AuthorizationGrantType getAuthorizationGrantType() {public OAuth2Authorization.Token<OAuth2AccessToken> getAccessToken() {@Nullablepublic OAuth2Authorization.Token<OAuth2RefreshToken> getRefreshToken() {@Nullablepublic <T extends OAuth2Token> OAuth2Authorization.Token<T> getToken(Class<T> tokenType) {@Nullablepublic <T extends OAuth2Token> OAuth2Authorization.Token<T> getToken(String tokenValue) {@Nullablepublic <T> T getAttribute(String name) {public boolean equals(Object obj) {public int hashCode() {public static OAuth2Authorization.Builder withRegisteredClient(RegisteredClient registeredClient) {//获取构造实例public static OAuth2Authorization.Builder from(OAuth2Authorization authorization) {static {serialVersionUID = Version.SERIAL_VERSION_UID;AUTHORIZED_SCOPE_ATTRIBUTE_NAME = OAuth2Authorization.class.getName().concat(".AUTHORIZED_SCOPE");}***********
内部类:Builderpublic static class Builder implements Serializable {private static final long serialVersionUID;private String id;private final String registeredClientId;private String principalName;private AuthorizationGrantType authorizationGrantType;private Map<Class<? extends OAuth2Token>, OAuth2Authorization.Token<?>> tokens = new HashMap();private final Map<String, Object> attributes = new HashMap();protected Builder(String registeredClientId) {this.registeredClientId = registeredClientId;}public OAuth2Authorization.Builder id(String id) {public OAuth2Authorization.Builder principalName(String principalName) {public OAuth2Authorization.Builder authorizationGrantType(AuthorizationGrantType authorizationGrantType) {public OAuth2Authorization.Builder accessToken(OAuth2AccessToken accessToken) {public OAuth2Authorization.Builder refreshToken(OAuth2RefreshToken refreshToken) {public <T extends OAuth2Token> OAuth2Authorization.Builder token(T token) {public <T extends OAuth2Token> OAuth2Authorization.Builder token(T token, Consumer<Map<String, Object>> metadataConsumer) {public OAuth2Authorization.Builder attribute(String name, Object value) {public OAuth2Authorization.Builder attributes(Consumer<Map<String, Object>> attributesConsumer) {public OAuth2Authorization build() {protected final OAuth2Authorization.Builder tokens(Map<Class<? extends OAuth2Token>, OAuth2Authorization.Token<?>> tokens) {static {serialVersionUID = Version.SERIAL_VERSION_UID;}}***********
内部类:Tokenpublic static class Token<T extends OAuth2Token> implements Serializable {private static final long serialVersionUID;protected static final String TOKEN_METADATA_NAMESPACE = "metadata.token.";public static final String INVALIDATED_METADATA_NAME;public static final String CLAIMS_METADATA_NAME;private final T token;private final Map<String, Object> metadata;protected Token(T token) {protected Token(T token, Map<String, Object> metadata) {public T getToken() {public boolean isInvalidated() {public boolean isExpired() {public boolean isBeforeUse() {public boolean isActive() {@Nullablepublic Map<String, Object> getClaims() {@Nullablepublic <V> V getMetadata(String name) {public Map<String, Object> getMetadata() {protected static Map<String, Object> defaultMetadata() {public boolean equals(Object obj) {public int hashCode() {static {serialVersionUID = Version.SERIAL_VERSION_UID;INVALIDATED_METADATA_NAME = "metadata.token.".concat("invalidated");CLAIMS_METADATA_NAME = "metadata.token.".concat("claims");}
AuthorizationGrantType:授权类型
public final class AuthorizationGrantType implements Serializable {private static final long serialVersionUID = 570L;public static final AuthorizationGrantType AUTHORIZATION_CODE = new AuthorizationGrantType("authorization_code");/** @deprecated */@Deprecatedpublic 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");public static final AuthorizationGrantType JWT_BEARER = new AuthorizationGrantType("urn:ietf:params:oauth:grant-type:jwt-bearer");private final String value;public AuthorizationGrantType(String value) {Assert.hasText(value, "value cannot be empty");this.value = value;}public String getValue() {return this.value;}public boolean equals(Object obj) {public int hashCode() {
OAuth2Token
public interface OAuth2Token {String getTokenValue();@Nullabledefault Instant getIssuedAt() {return null;}@Nullabledefault Instant getExpiresAt() {return null;}
}
Jwt
public class Jwt extends AbstractOAuth2Token implements JwtClaimAccessor {private final Map<String, Object> headers;private final Map<String, Object> claims;public Jwt(String tokenValue, Instant issuedAt, Instant expiresAt, Map<String, Object> headers, Map<String, Object> claims) {super(tokenValue, issuedAt, expiresAt);Assert.notEmpty(headers, "headers cannot be empty");Assert.notEmpty(claims, "claims cannot be empty");this.headers = Collections.unmodifiableMap(new LinkedHashMap(headers));this.claims = Collections.unmodifiableMap(new LinkedHashMap(claims));}public Map<String, Object> getHeaders() {public Map<String, Object> getClaims() {public static Jwt.Builder withTokenValue(String tokenValue) {//获取构造实例**********
内部类:Builderpublic static final class Builder {private String tokenValue;private final Map<String, Object> claims;private final Map<String, Object> headers;private Builder(String tokenValue) {public Jwt.Builder tokenValue(String tokenValue) {public Jwt.Builder claim(String name, Object value) {public Jwt.Builder claims(Consumer<Map<String, Object>> claimsConsumer) {public Jwt.Builder header(String name, Object value) {public Jwt.Builder headers(Consumer<Map<String, Object>> headersConsumer) {public Jwt.Builder audience(Collection<String> audience) {return this.claim("aud", audience);}public Jwt.Builder expiresAt(Instant expiresAt) {this.claim("exp", expiresAt);return this;}public Jwt.Builder jti(String jti) {this.claim("jti", jti);return this;}public Jwt.Builder issuedAt(Instant issuedAt) {this.claim("iat", issuedAt);return this;}public Jwt.Builder issuer(String issuer) {this.claim("iss", issuer);return this;}public Jwt.Builder notBefore(Instant notBefore) {this.claim("nbf", notBefore);return this;}public Jwt.Builder subject(String subject) {this.claim("sub", subject);return this;}public Jwt build() {Instant iat = this.toInstant(this.claims.get("iat"));Instant exp = this.toInstant(this.claims.get("exp"));return new Jwt(this.tokenValue, iat, exp, this.headers, this.claims);}private Instant toInstant(Object timestamp) {
OAuth2AuthorizationService:OAuth2Autjorization读写接口
public interface OAuth2AuthorizationService {void save(OAuth2Authorization authorization);void remove(OAuth2Authorization authorization);@NullableOAuth2Authorization findById(String id);@NullableOAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType);
}
InMemoryOAuth2AuthorizationService
public final class InMemoryOAuth2AuthorizationService implements OAuth2AuthorizationService {private int maxInitializedAuthorizations; //内存中存储的OAuth2Authorization数量,默认100private Map<String, OAuth2Authorization> initializedAuthorizations;private final Map<String, OAuth2Authorization> authorizations;InMemoryOAuth2AuthorizationService(int maxInitializedAuthorizations) {public InMemoryOAuth2AuthorizationService() {public InMemoryOAuth2AuthorizationService(OAuth2Authorization... authorizations) {public InMemoryOAuth2AuthorizationService(List<OAuth2Authorization> authorizations) {public void save(OAuth2Authorization authorization) {public void remove(OAuth2Authorization authorization) {@Nullablepublic OAuth2Authorization findById(String id) {@Nullablepublic OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) {private static boolean isComplete(OAuth2Authorization authorization) {private static boolean hasToken(OAuth2Authorization authorization, String token, @Nullable OAuth2TokenType tokenType) {private static boolean matchesState(OAuth2Authorization authorization, String token) {private static boolean matchesAuthorizationCode(OAuth2Authorization authorization, String token) {private static boolean matchesAccessToken(OAuth2Authorization authorization, String token) {private static boolean matchesRefreshToken(OAuth2Authorization authorization, String token) {*********
内部类:MaxSizeHashMapprivate static final class MaxSizeHashMap<K, V> extends LinkedHashMap<K, V> {private final int maxSize;private MaxSizeHashMap(int maxSize) {this.maxSize = maxSize;}protected boolean removeEldestEntry(Entry<K, V> eldest) {return this.size() > this.maxSize;}}
JdbcOAuth2AuthorizationService:数据库读写操作
public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationService {private static final String COLUMN_NAMES = "id, registered_client_id, principal_name, authorization_grant_type, attributes, state, authorization_code_value, authorization_code_issued_at, authorization_code_expires_at,authorization_code_metadata,access_token_value,access_token_issued_at,access_token_expires_at,access_token_metadata,access_token_type,access_token_scopes,oidc_id_token_value,oidc_id_token_issued_at,oidc_id_token_expires_at,oidc_id_token_metadata,refresh_token_value,refresh_token_issued_at,refresh_token_expires_at,refresh_token_metadata";private static final String TABLE_NAME = "oauth2_authorization";private static final String PK_FILTER = "id = ?";private static final String UNKNOWN_TOKEN_TYPE_FILTER = "state = ? OR authorization_code_value = ? OR access_token_value = ? OR refresh_token_value = ?";private static final String STATE_FILTER = "state = ?";private static final String AUTHORIZATION_CODE_FILTER = "authorization_code_value = ?";private static final String ACCESS_TOKEN_FILTER = "access_token_value = ?";private static final String REFRESH_TOKEN_FILTER = "refresh_token_value = ?";private static final String LOAD_AUTHORIZATION_SQL = "SELECT id, registered_client_id, principal_name, authorization_grant_type, attributes, state, authorization_code_value, authorization_code_issued_at, authorization_code_expires_at,authorization_code_metadata,access_token_value,access_token_issued_at,access_token_expires_at,access_token_metadata,access_token_type,access_token_scopes,oidc_id_token_value,oidc_id_token_issued_at,oidc_id_token_expires_at,oidc_id_token_metadata,refresh_token_value,refresh_token_issued_at,refresh_token_expires_at,refresh_token_metadata FROM oauth2_authorization WHERE ";private static final String SAVE_AUTHORIZATION_SQL = "INSERT INTO oauth2_authorization (id, registered_client_id, principal_name, authorization_grant_type, attributes, state, authorization_code_value, authorization_code_issued_at, authorization_code_expires_at,authorization_code_metadata,access_token_value,access_token_issued_at,access_token_expires_at,access_token_metadata,access_token_type,access_token_scopes,oidc_id_token_value,oidc_id_token_issued_at,oidc_id_token_expires_at,oidc_id_token_metadata,refresh_token_value,refresh_token_issued_at,refresh_token_expires_at,refresh_token_metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";private static final String UPDATE_AUTHORIZATION_SQL = "UPDATE oauth2_authorization SET registered_client_id = ?, principal_name = ?, authorization_grant_type = ?, attributes = ?, state = ?, authorization_code_value = ?, authorization_code_issued_at = ?, authorization_code_expires_at = ?, authorization_code_metadata = ?, access_token_value = ?, access_token_issued_at = ?, access_token_expires_at = ?, access_token_metadata = ?, access_token_type = ?, access_token_scopes = ?, oidc_id_token_value = ?, oidc_id_token_issued_at = ?, oidc_id_token_expires_at = ?, oidc_id_token_metadata = ?, refresh_token_value = ?, refresh_token_issued_at = ?, refresh_token_expires_at = ?, refresh_token_metadata = ? WHERE id = ?";private static final String REMOVE_AUTHORIZATION_SQL = "DELETE FROM oauth2_authorization WHERE id = ?";private static Map<String, JdbcOAuth2AuthorizationService.ColumnMetadata> columnMetadataMap;private final JdbcOperations jdbcOperations;private final LobHandler lobHandler;private RowMapper<OAuth2Authorization> authorizationRowMapper;private Function<OAuth2Authorization, List<SqlParameterValue>> authorizationParametersMapper;public JdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) {public JdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository, LobHandler lobHandler) {public void save(OAuth2Authorization authorization) {public void remove(OAuth2Authorization authorization) {@Nullablepublic OAuth2Authorization findById(String id) {@Nullablepublic OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) {public final void setAuthorizationRowMapper(RowMapper<OAuth2Authorization> authorizationRowMapper) {public final void setAuthorizationParametersMapper(Function<OAuth2Authorization, List<SqlParameterValue>> authorizationParametersMapper) {protected final JdbcOperations getJdbcOperations() {protected final LobHandler getLobHandler() {protected final RowMapper<OAuth2Authorization> getAuthorizationRowMapper() {protected final Function<OAuth2Authorization, List<SqlParameterValue>> getAuthorizationParametersMapper() {private void updateAuthorization(OAuth2Authorization authorization) {private void insertAuthorization(OAuth2Authorization authorization) {private static void initColumnMetadata(JdbcOperations jdbcOperations) {private static JdbcOAuth2AuthorizationService.ColumnMetadata getColumnMetadata(JdbcOperations jdbcOperations, String columnName, int defaultDataType) {private static SqlParameterValue mapToSqlParameter(String columnName, String value) {private OAuth2Authorization findBy(String filter, List<SqlParameterValue> parameters) {**********
内部类:ColumnMetadataprivate static final class ColumnMetadata {private final String columnName;private final int dataType;private ColumnMetadata(String columnName, int dataType) {private String getColumnName() {private int getDataType() {**********
内部类:LobCreatorArgumentPreparedStatementSetterprivate static final class LobCreatorArgumentPreparedStatementSetter extends ArgumentPreparedStatementSetter {private final LobCreator lobCreator;private LobCreatorArgumentPreparedStatementSetter(LobCreator lobCreator, Object[] args) {protected void doSetValue(PreparedStatement ps, int parameterPosition, Object argValue) throws SQLException {**********
内部类:OAuth2AuthorizationParametersMapperpublic static class OAuth2AuthorizationParametersMapper implements Function<OAuth2Authorization, List<SqlParameterValue>> {private ObjectMapper objectMapper = new ObjectMapper();public OAuth2AuthorizationParametersMapper() {public List<SqlParameterValue> apply(OAuth2Authorization authorization) {public final void setObjectMapper(ObjectMapper objectMapper) {protected final ObjectMapper getObjectMapper() {private String writeMap(Map<String, Object> data) {private <T extends OAuth2Token> List<SqlParameterValue> toSqlParameterList(String tokenColumnName, String tokenMetadataColumnName, Token<T> token) {**********
内部类:OAuth2AuthorizationRowMapperpublic static class OAuth2AuthorizationRowMapper implements RowMapper<OAuth2Authorization> {private final RegisteredClientRepository registeredClientRepository;private LobHandler lobHandler = new DefaultLobHandler();private ObjectMapper objectMapper = new ObjectMapper();public OAuth2AuthorizationRowMapper(RegisteredClientRepository registeredClientRepository) {public OAuth2Authorization mapRow(ResultSet rs, int rowNum) throws SQLException {private String getLobValue(ResultSet rs, String columnName) throws SQLException {public final void setLobHandler(LobHandler lobHandler) {public final void setObjectMapper(ObjectMapper objectMapper) {protected final LobHandler getLobHandler() {protected final ObjectMapper getObjectMapper() {protected final RegisteredClientRepository getRegisteredClientRepository() {private Map<String, Object> parseMap(String data) {
权限存储
OAuth2AuthorizationConsent
public final class OAuth2AuthorizationConsent implements Serializable {private static final long serialVersionUID;private static final String AUTHORITIES_SCOPE_PREFIX = "SCOPE_";private final String registeredClientId;private final String principalName;private final Set<GrantedAuthority> authorities;private OAuth2AuthorizationConsent(String registeredClientId, String principalName, Set<GrantedAuthority> authorities) {public String getPrincipalName() {public String getRegisteredClientId() {public Set<GrantedAuthority> getAuthorities() {public Set<String> getScopes() {public boolean equals(Object obj) {public int hashCode() {public static OAuth2AuthorizationConsent.Builder from(OAuth2AuthorizationConsent authorizationConsent) {public static OAuth2AuthorizationConsent.Builder withId(@NonNull String registeredClientId, @NonNull String principalName) {//获取实例构造类static {serialVersionUID = Version.SERIAL_VERSION_UID;}**********
内部类:Builderpublic static final class Builder implements Serializable {private static final long serialVersionUID;private final String registeredClientId;private final String principalName;private final Set<GrantedAuthority> authorities;private Builder(String registeredClientId, String principalName) {private Builder(String registeredClientId, String principalName, Set<GrantedAuthority> authorities) {public OAuth2AuthorizationConsent.Builder scope(String scope) {this.authority(new SimpleGrantedAuthority("SCOPE_" + scope));return this;}public OAuth2AuthorizationConsent.Builder authority(GrantedAuthority authority) {this.authorities.add(authority);return this;}public OAuth2AuthorizationConsent.Builder authorities(Consumer<Set<GrantedAuthority>> authoritiesConsumer) {public OAuth2AuthorizationConsent build() {static {serialVersionUID = Version.SERIAL_VERSION_UID;}
OAuth2AuthorizationConsentService
public interface OAuth2AuthorizationConsentService {void save(OAuth2AuthorizationConsent authorizationConsent);void remove(OAuth2AuthorizationConsent authorizationConsent);@NullableOAuth2AuthorizationConsent findById(String registeredClientId, String principalName);
}
InMemoryOAuth2AuthorizationConsentService
public final class InMemoryOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService {private final Map<Integer, OAuth2AuthorizationConsent> authorizationConsents;public InMemoryOAuth2AuthorizationConsentService() {this(Collections.emptyList());}public InMemoryOAuth2AuthorizationConsentService(OAuth2AuthorizationConsent... authorizationConsents) {this(Arrays.asList(authorizationConsents));}public InMemoryOAuth2AuthorizationConsentService(List<OAuth2AuthorizationConsent> authorizationConsents) {this.authorizationConsents = new ConcurrentHashMap();Assert.notNull(authorizationConsents, "authorizationConsents cannot be null");authorizationConsents.forEach((authorizationConsent) -> {Assert.notNull(authorizationConsent, "authorizationConsent cannot be null");int id = getId(authorizationConsent);Assert.isTrue(!this.authorizationConsents.containsKey(id), "The authorizationConsent must be unique. Found duplicate, with registered client id: [" + authorizationConsent.getRegisteredClientId() + "] and principal name: [" + authorizationConsent.getPrincipalName() + "]");this.authorizationConsents.put(id, authorizationConsent);});}public void save(OAuth2AuthorizationConsent authorizationConsent) {public void remove(OAuth2AuthorizationConsent authorizationConsent) {@Nullablepublic OAuth2AuthorizationConsent findById(String registeredClientId, String principalName) {Assert.hasText(registeredClientId, "registeredClientId cannot be empty");Assert.hasText(principalName, "principalName cannot be empty");int id = getId(registeredClientId, principalName);return (OAuth2AuthorizationConsent)this.authorizationConsents.get(id);}private static int getId(String registeredClientId, String principalName) {private static int getId(OAuth2AuthorizationConsent authorizationConsent) {
JdbcOAuth2AuthorizationConsentService
public class JdbcOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService {private static final String COLUMN_NAMES = "registered_client_id, principal_name, authorities";private static final String TABLE_NAME = "oauth2_authorization_consent";private static final String PK_FILTER = "registered_client_id = ? AND principal_name = ?";private static final String LOAD_AUTHORIZATION_CONSENT_SQL = "SELECT registered_client_id, principal_name, authorities FROM oauth2_authorization_consent WHERE registered_client_id = ? AND principal_name = ?";private static final String SAVE_AUTHORIZATION_CONSENT_SQL = "INSERT INTO oauth2_authorization_consent (registered_client_id, principal_name, authorities) VALUES (?, ?, ?)";private static final String UPDATE_AUTHORIZATION_CONSENT_SQL = "UPDATE oauth2_authorization_consent SET authorities = ? WHERE registered_client_id = ? AND principal_name = ?";private static final String REMOVE_AUTHORIZATION_CONSENT_SQL = "DELETE FROM oauth2_authorization_consent WHERE registered_client_id = ? AND principal_name = ?";private final JdbcOperations jdbcOperations;private RowMapper<OAuth2AuthorizationConsent> authorizationConsentRowMapper;private Function<OAuth2AuthorizationConsent, List<SqlParameterValue>> authorizationConsentParametersMapper;public JdbcOAuth2AuthorizationConsentService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) {public void save(OAuth2AuthorizationConsent authorizationConsent) {public void remove(OAuth2AuthorizationConsent authorizationConsent) {@Nullablepublic OAuth2AuthorizationConsent findById(String registeredClientId, String principalName) {public final void setAuthorizationConsentRowMapper(RowMapper<OAuth2AuthorizationConsent> authorizationConsentRowMapper) {public final void setAuthorizationConsentParametersMapper(Function<OAuth2AuthorizationConsent, List<SqlParameterValue>> authorizationConsentParametersMapper) {protected final JdbcOperations getJdbcOperations() {protected final RowMapper<OAuth2AuthorizationConsent> getAuthorizationConsentRowMapper() {protected final Function<OAuth2AuthorizationConsent, List<SqlParameterValue>> getAuthorizationConsentParametersMapper() {private void updateAuthorizationConsent(OAuth2AuthorizationConsent authorizationConsent) {private void insertAuthorizationConsent(OAuth2AuthorizationConsent authorizationConsent) {*********
内部类:OAuth2AuthorizationConsentParametersMapperpublic static class OAuth2AuthorizationConsentParametersMapper implements Function<OAuth2AuthorizationConsent, List<SqlParameterValue>> {public OAuth2AuthorizationConsentParametersMapper() {}public List<SqlParameterValue> apply(OAuth2AuthorizationConsent authorizationConsent) {*********
内部类:OAuth2AuthorizationConsentRowMapperpublic static class OAuth2AuthorizationConsentRowMapper implements RowMapper<OAuth2AuthorizationConsent> {private final RegisteredClientRepository registeredClientRepository;public OAuth2AuthorizationConsentRowMapper(RegisteredClientRepository registeredClientRepository) {public OAuth2AuthorizationConsent mapRow(ResultSet rs, int rowNum) throws SQLException {protected final RegisteredClientRepository getRegisteredClientRepository() {
授权路径设置
ProviderSettings
public final class ProviderSettings extends AbstractSettings {private ProviderSettings(Map<String, Object> settings) {super(settings);}public String getIssuer() {public String getTokenEndpoint() {public String getJwkSetEndpoint() {public String getAuthorizationEndpoint() {public String getTokenRevocationEndpoint() {public String getTokenIntrospectionEndpoint() {public String getOidcUserInfoEndpoint() {public String getOidcClientRegistrationEndpoint() {public static ProviderSettings.Builder builder() { //默认路径return (new ProviderSettings.Builder()).authorizationEndpoint("/oauth2/authorize").tokenEndpoint("/oauth2/token").jwkSetEndpoint("/oauth2/jwks").tokenRevocationEndpoint("/oauth2/revoke").tokenIntrospectionEndpoint("/oauth2/introspect").oidcClientRegistrationEndpoint("/connect/register").oidcUserInfoEndpoint("/userinfo");}public static ProviderSettings.Builder withSettings(Map<String, Object> settings) {//获取构造实例对象**********
内部类:Builderpublic static class Builder extends AbstractBuilder<ProviderSettings, ProviderSettings.Builder> {private Builder() {}public ProviderSettings.Builder issuer(String issuer) {public ProviderSettings.Builder authorizationEndpoint(String authorizationEndpoint) {public ProviderSettings.Builder tokenEndpoint(String tokenEndpoint) {public ProviderSettings.Builder jwkSetEndpoint(String jwkSetEndpoint) {public ProviderSettings.Builder tokenRevocationEndpoint(String tokenRevocationEndpoint) {public ProviderSettings.Builder tokenIntrospectionEndpoint(String tokenIntrospectionEndpoint) {public ProviderSettings.Builder oidcClientRegistrationEndpoint(String oidcClientRegistrationEndpoint) {public ProviderSettings.Builder oidcUserInfoEndpoint(String oidcUserInfoEndpoint) {return (ProviderSettings.Builder)this.setting(Provider.OIDC_USER_INFO_ENDPOINT, oidcUserInfoEndpoint);}public ProviderSettings build() {return new ProviderSettings(this.getSettings());}
授权客户端
OAuth2ClientProperties:客户端配置相关属性,到授权中心进行认证
@ConfigurationProperties(prefix = "spring.security.oauth2.client"
)
public class OAuth2ClientProperties implements InitializingBean {private final Map<String, OAuth2ClientProperties.Provider> provider = new HashMap();private final Map<String, OAuth2ClientProperties.Registration> registration = new HashMap();public OAuth2ClientProperties() {}public Map<String, OAuth2ClientProperties.Provider> getProvider() {public Map<String, OAuth2ClientProperties.Registration> getRegistration() {public void validate() {public void afterPropertiesSet() {private void validateRegistration(OAuth2ClientProperties.Registration registration) {***********
Provider:静态内部类,授权服务uripublic static class Provider {private String authorizationUri;private String tokenUri;private String userInfoUri;private String userInfoAuthenticationMethod;private String userNameAttribute;private String jwkSetUri;private String issuerUri;public Provider() {}public void setTokenUri(String tokenUri) {public void setJwkSetUri(String jwkSetUri) {public void setIssuerUri(String issuerUri) {public void setUserInfoUri(String userInfoUri) {public void setAuthorizationUri(String authorizationUri) {public void setUserNameAttribute(String userNameAttribute) {public void setUserInfoAuthenticationMethod(String userInfoAuthenticationMethod) {public String getTokenUri() {public String getIssuerUri() {public String getJwkSetUri() {public String getUserInfoUri() {public String getAuthorizationUri() {public String getUserNameAttribute() {public String getUserInfoAuthenticationMethod() {***********
Registration:静态内部类,客户端注册信息public static class Registration {private String provider;private String clientId;private String clientSecret;private String clientAuthenticationMethod;private String authorizationGrantType;private String redirectUri;private Set<String> scope;private String clientName;public Registration() {}public void setScope(Set<String> scope) {public void setClientId(String clientId) {public void setProvider(String provider) {public void setClientName(String clientName) {public void setRedirectUri(String redirectUri) {public void setClientSecret(String clientSecret) {public void setAuthorizationGrantType(String authorizationGrantType) {public void setClientAuthenticationMethod(String clientAuthenticationMethod) {public String getClientId() {public String getProvider() {public Set<String> getScope() {public String getClientName() {public String getRedirectUri() {public String getClientSecret() {public String getAuthorizationGrantType() {public String getClientAuthenticationMethod() {