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等安全頭部