Spring Security 教程(22)、验证管理器和命名空间

内存认证(测试用)

Spring Security 配图
Spring Security 配图
Spring Security 配图

1
2
3
4
5
6
7
8
9
10
11
12
13
http.authenticationManager(new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
if ("admin".equals(authentication.getName())
&& "password".equals(authentication.getCredentials())) {
return new UsernamePasswordAuthenticationToken(
"admin", "password",
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
}
throw new BadCredentialsException("Invalid credentials");
}
});

或者使用 AuthenticationManagerBuilder:

1
2
3
4
5
6
auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("admin"))
.roles("ADMIN")
.and()
.withUser("user").password(passwordEncoder().encode("user"))
.roles("USER");

JDBC 认证(数据库)

1
2
3
4
5
6
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery(
"select username, password, enabled from users where username = ?")
.authoritiesByUsernameQuery(
"select username, authority from authorities where username = ?");

对应的数据库表结构:

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE users (
username VARCHAR(50) PRIMARY KEY,
password VARCHAR(255) NOT NULL,
enabled BOOLEAN DEFAULT true
);

CREATE TABLE authorities (
username VARCHAR(50),
authority VARCHAR(50),
PRIMARY KEY (username, authority),
FOREIGN KEY (username) REFERENCES users(username)
);

LDAP 认证

1
2
3
4
5
6
7
auth.ldapAuthentication()
.contextSource()
.root("dc=example,dc=com")
.ldif("classpath:users.ldif")
.and()
.ldapAuthoritiesPopulator()
.dnPattern("uid={0},ou=people");

LDAP 配置的关键参数:

  • root:LDAP 根目录
  • ldif:用于测试的 LDIF 数据文件
  • dnPattern:用户 DN 模式,{0} 是用户名占位符
  • userSearchFilter:用户搜索过滤器
  • groupSearchFilter:组搜索过滤器

自定义 AuthenticationProvider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();

// 自定义认证逻辑
if (validateUser(username, password)) {
return new UsernamePasswordAuthenticationToken(
username, password, getAuthorities(username));
}
throw new BadCredentialsException("Invalid credentials");
}

@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}

认证后端选择建议

authentication-manager-namespace 配图
authentication-manager-namespace 配图
authentication-manager-namespace 配图

场景 推荐认证后端
开发测试 InMemory
企业应用 JDBC(数据库)
大型组织 LDAP / Active Directory
分布式系统 OAuth 2.0 / JWT
自定义需求 自定义 AuthenticationProvider