Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架,其认证和授权实现机制如下:
一、认证(Authentication)实现
1. 核心组件
AuthenticationManager:认证入口点,委托给AuthenticationProvider
AuthenticationProvider:实际执行认证逻辑
UserDetailsService:加载用户特定数据
SecurityContextHolder:存储当前安全上下文
2. 认证流程
用户提交凭证(用户名/密码等)
UsernamePasswordAuthenticationFilter拦截请求,创建Authentication对象
ProviderManager选择合适的AuthenticationProvider
DaoAuthenticationProvider调用UserDetailsService加载用户详情
PasswordEncoder验证密码
认证成功后构建完全填充的Authentication对象
将Authentication存入SecurityContext
3. 常用认证方式
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 内存认证
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER");
// JDBC认证
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from users where username=?")
.authoritiesByUsernameQuery("select username,authority from authorities where username=?");
// 自定义UserDetailsService
auth.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
二、授权(Authorization)实现
1. 核心概念
GrantedAuthority:授予用户的权限(如角色)
ConfigAttribute:访问资源所需的权限
AccessDecisionManager:做出最终的访问控制决策
AccessDecisionVoter:投票决定是否授予访问权限
2. 授权流程
FilterSecurityInterceptor拦截请求
获取请求资源的配置属性(所需权限)
AccessDecisionManager收集投票
基于投票结果允许/拒绝访问
3. 授权配置方式
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // 基于角色
.antMatchers("/api/**").hasAuthority("API_ACCESS") // 基于权限
.antMatchers("/public/**").permitAll() // 公开访问
.anyRequest().authenticated() // 其他请求需要认证
.and()
.formLogin() // 表单登录
.and()
.httpBasic(); // HTTP基本认证
}
三、高级特性
1. 方法级安全
@PreAuthorize("hasRole('ADMIN') or #user.username == authentication.name")
public void updateUser(User user) {
// ...
}
@PostAuthorize("returnObject.owner == authentication.name")
public Document getDocument(Long id) {
// ...
}
@Secured("ROLE_ADMIN")
public void adminOperation() {
// ...
}
2. 自定义认证逻辑
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
CustomUser user = userDetailsService.loadUserByUsername(username);
if (passwordEncoder.matches(password, user.getPassword())) {
return new UsernamePasswordAuthenticationToken(
user, password, user.getAuthorities());
} else {
throw new BadCredentialsException("Authentication failed");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
3. OAuth2集成
@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.secret(passwordEncoder.encode("secret"))
.authorizedGrantTypes("authorization_code", "refresh_token")
.scopes("read", "write")
.redirectUris("http://localhost:8080/login/oauth2/code/custom");
}
}
四、实际应用建议
密码安全:始终使用强密码编码器(如BCrypt)
CSRF防护:生产环境必须启用
会话管理:合理配置会话固定保护和并发控制
CORS配置:根据实际需求精细控制
安全头部:启用XSS保护、HSTS等安全头部