学习 org.springframework.security.core.userdetails.User类。
public class User {
private String password;
private final String username;
...
// 初始化UserBuilder对象的PasswordEncoder属性
// 这个方法被弃用,我们简单看一下
@Deprecated
public static UserBuilder withDefaultPasswordEncoder() {
logger.warn("User.withDefaultPasswordEncoder() is considered unsafe for
production "
+ "and is only intended for sample applications.");
// 1. 使用PasswordEncoderFactories创建一个DelegatingPasswordEncoder对象
// 储存bcrypt:BCryptPasswordEncoder、ldap:LdapShaPasswordEncoder等
// 2. String encode(CharSequence rawPassword)方法中,使用{idForEncode}+
// passwordEncoder(rawPassword),例如{bcrypt}+BCryptPasswordEncoder.encode
// (rawPassword)
// 3. 密码匹配。使用前端输入密码与数据库中的密码匹配
// boolean matches(CharSequence rawPassword, String prefixEncodedPassword)
// 该方法主要行为:a.根据prefixEncodedPassword获取到passwordEncoder。b.使用
// passwordEncoder.match(rawPassword,prefixEncodedPassword去掉{idForEncode}).
PasswordEncoder encoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
return builder().passwordEncoder(encoder::encode);
}
// 创建UserBuilder对象
public static UserBuilder builder() {
return new UserBuilder();
}
// 创建UserBuilder对象,初始化其属性username
public static UserBuilder withUsername(String username) {
return builder().username(username);
}
// 参数为对象
// 用 withUsername(String username)方式,初始化UserBuilder的其他属性
public static UserBuilder withUserDetails(UserDetails userDetails) {
// @formatter:off
return withUsername(userDetails.getUsername())
.password(userDetails.getPassword())
.accountExpired(!userDetails.isAccountNonExpired())
.accountLocked(!userDetails.isAccountNonLocked())
.authorities(userDetails.getAuthorities())
.credentialsExpired(!userDetails.isCredentialsNonExpired())
.disabled(!userDetails.isEnabled());
// @formatter:on
}
// 创建公共静态内部类
// 其属性与User类大致一样
public static final class UserBuilder {
private String username;
private String password;
// 调用时机可以放在build行为中
private Function<String, String> passwordEncoder = (password) -> password;
// 禁止 new UserBuilder() 对象
private UserBuilder() {
}
// 以下面行为初始化UserBuilder的username属性。其他属性同样如此
public UserBuilder username(String username) {
Assert.notNull(username, "username cannot be null");
this.username = username;
return this;
}
// 核心 build行为
public UserDetails build() {
// 调用passwordEncoder的行为
String encodedPassword = this.passwordEncoder.apply(this.password);
// 使用UserBuilder中的属性,初始化User中的属性
return new User(this.username, encodedPassword,...);
}
}
}
public class UserTests {
@Test
public void testBuildUserWithNoAuthorities() {
// 方式1
UserDetails user = User.builder()
.username("user")
.password("password")
.build();
// 方式2
// 方式3:User.withUserDetails(userDetails).passwordEncoder(p->p)
UserDetails user = User.withUsername("user")
.password("password")
.build();
}
}
学习 org.springframework.security.oauth2.client.registration.ClientRegistration类。
public final class ClientRegistration {
private String registrationId;
private String clientId;
private String clientSecret;
private ClientAuthenticationMethod clientAuthenticationMethod;
private AuthorizationGrantType authorizationGrantType;
private String redirectUri;
private Set<String> scopes;
private ProviderDetails providerDetails;
private String clientName;
public static final class Builder {
private String registrationId;
private String clientId;
private String clientSecret;
private ClientAuthenticationMethod clientAuthenticationMethod;
private AuthorizationGrantType authorizationGrantType;
private String redirectUri;
private Set<String> scopes;
private String authorizationUri;
private String tokenUri;
private String userInfoUri;
private AuthenticationMethod userInfoAuthenticationMethod;
private String userNameAttributeName;
private String jwkSetUri;
private String issuerUri;
private Map<String, Object> configurationMetadata;
private String clientName;
private Builder(String registrationId) {
...
this.registrationId = registrationId;
}
// AuthenticationMethod(HEADER,FORM,QUERY)
private Builder(ClientRegistration clientRegistration) {
this.userInfoAuthenticationMethod = AuthenticationMethod.HEADER;
this.configurationMetadata = Collections.emptyMap();
this.registrationId = clientRegistration.registrationId;
this.clientId = clientRegistration.clientId;
this.clientSecret = clientRegistration.clientSecret;
this.clientAuthenticationMethod = clientRegistration.clientAuthenticationMethod;
this.authorizationGrantType = clientRegistration.authorizationGrantType;
this.redirectUri = clientRegistration.redirectUri;
this.scopes = clientRegistration.scopes != null ? new HashSet(clientRegistration.scopes) : null;
this.authorizationUri = clientRegistration.providerDetails.authorizationUri;
this.tokenUri = clientRegistration.providerDetails.tokenUri;
this.userInfoUri = clientRegistration.providerDetails.userInfoEndpoint.uri;
this.jwkSetUri = clientRegistration.providerDetails.jwkSetUri;
this.issuerUri = clientRegistration.providerDetails.issuerUri;
this.clientName = clientRegistration.clientName;
}
public Builder issuerUri(String issuerUri) {
this.issuerUri = issuerUri;
return this;
}
// AuthorizationGrantType(AUTHORIZATION_CODE,IMPLICIT,REFRESH_TOKEN,
// CLIENT_CREDENTIALS,PASSWORD,JWT_BEARER)
public ClientRegistration build() {
Assert.notNull(this.authorizationGrantType, "authorizationGrantType cannot be null");
if (AuthorizationGrantType.CLIENT_CREDENTIALS.equals(this.authorizationGrantType)) {
this.validateClientCredentialsGrantType();
} else if (AuthorizationGrantType.PASSWORD.equals(this.authorizationGrantType)) {
this.validatePasswordGrantType();
} else if (AuthorizationGrantType.IMPLICIT.equals(this.authorizationGrantType)) {
this.validateImplicitGrantType();
} else if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(this.authorizationGrantType)) {
this.validateAuthorizationCodeGrantType();
}
this.validateScopes();
return this.create();
}
}
}