import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { // 堆代码 duidaima.com private final AuthenticationManager authenticationManager; public CustomAuthenticationFilter(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String username = request.getParameter("username"); String password = request.getParameter("password"); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); return authenticationManager.authenticate(authenticationToken); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { // 可以返回用户信息或 JWT 令牌 response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); ObjectMapper objectMapper = new ObjectMapper(); String token = "some_generated_jwt"; // 实际上要生成 JWT response.getWriter().write(objectMapper.writeValueAsString("token: " + token)); } @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write("{\"error\": \"" + failed.getMessage() + "\"}"); } }2. 配置 Spring Security 的详细步骤
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置用户存储方式 auth.inMemoryAuthentication() .withUser("user").password("{noop}password").roles("USER") .and() .withUser("admin").password("{noop}admin").roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { CustomAuthenticationFilter customFilter = new CustomAuthenticationFilter(authenticationManagerBean()); customFilter.setFilterProcessesUrl("/login"); // 自定义登录路径 http.csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() // 允许访问登录接口 .anyRequest().authenticated() // 其他请求需要认证 .and() .addFilter(customFilter) // 添加自定义认证过滤器 .logout() .logoutUrl("/logout") // 自定义登出路径 .logoutSuccessUrl("/login?logout") // 登出成功后的重定向地址 .invalidateHttpSession(true) // 登出时使 HTTP 会话失效 .deleteCookies("JSESSIONID"); // 删除指定的 Cookie } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }三、登出功能的实现
deleteCookies("JSESSIONID"):在登出时删除指定的 Cookie。