明白!我帮你写一个Spring Security详解,每个核心场景都附带完整示例代码,覆盖认证、授权、用户存储、密码加密、自定义登录、方法级安全等,便于直接拿来用或学习。
Spring Security详解 —— 场景+代码全覆盖
1. 基础认证(In-Memory 用户)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("alice").password("{noop}123456").roles("USER")
.and()
.withUser("admin").password("{noop}admin").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated() // 所有请求需要认证
.and()
.formLogin().permitAll() // 开启表单登录
.and()
.logout().permitAll();
}
}
2. 基于数据库的认证与密码加密
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?")
.authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().formLogin().permitAll()
.and().logout().permitAll();
}
}
3. URL基于角色权限访问控制
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/", "/home", "/public/**").permitAll()
.anyRequest().authenticated()
.and().formLogin().permitAll();
}
4. 自定义登录页面和登录成功跳转
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/login") // 自定义登录页
.defaultSuccessUrl("/dashboard") // 登录成功跳转
.failureUrl("/login?error") // 登录失败跳转
.permitAll();
}
5. 方法级权限控制(注解)
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { }
@Service
public class ProductService {
@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyOperation() {
// 管理员专属操作
}
@PreAuthorize("hasAuthority('PRODUCT_READ')")
public void userReadOperation() {
// 拥有PRODUCT_READ权限可执行
}
}
6. 用户注销配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout()
.logoutUrl("/perform_logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
}
7. CSRF防护示例
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
8. 基于JWT的无状态认证示例(简要)
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
throws ServletException, IOException {
String token = req.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
// 验证token逻辑
Authentication auth = getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
chain.doFilter(req, res);
}
}
在SecurityConfig
中注册过滤器:
http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
9. 异常处理示例(访问拒绝)
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.accessDeniedHandler((request, response, accessDeniedException) -> {
response.sendRedirect("/403");
});
}
10. CORS跨域支持配置
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(List.of("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
}
发表回复