SpringSecurity6.1
自己重写UsernamePasswordAuthenticationFilter
package com.hw.example.admin.config.security.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hw.example.admin.config.security.domain.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.io.IOException;
/**
* @author : guanzheng
* @date : 2023/6/26 15:17
*/
public class JsonLoginFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//获取请求头,据此判断请求参数类型
String contentType = request.getContentType();
if (MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(contentType)) {
//说明请求参数是 JSON
if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = null;
String password = null;
try {
//解析请求体中的 JSON 参数
User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
username = user.getUsername();
username = (username != null) ? username.trim() : "";
password = user.getPassword();
password = (password != null) ? password : "";
} catch (IOException e) {
throw new RuntimeException(e);
}
//构建登录令牌
UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
//执行真正的登录操作
Authentication auth = this.getAuthenticationManager().authenticate(authRequest);
SecurityContextHolder.getContext().setAuthentication(auth);
return auth;
}
return super.attemptAuthentication(request,response);
}
}
package com.hw.example.admin.config.security;
import com.hw.example.admin.config.security.filter.JsonLoginFilter;
import com.hw.example.admin.config.security.handler.LoginFailureHandler;
import com.hw.example.admin.config.security.handler.LoginSuccessHandler;
import com.hw.example.admin.config.security.handler.LogoutHandler;
import com.hw.example.admin.config.security.handler.MyPasswordEncoder;
import com.hw.example.admin.config.security.service.UserDetailServiceImpl;
import com.hw.example.common.util.http.HttpUtil;
import com.hw.example.common.web.component.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.io.IOException;
/**
* @author : guanzheng
* @date : 2023/6/25 9:03
*/
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Autowired
UserDetailServiceImpl userDetailService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
//认证请求配置
http.authorizeHttpRequests()
//允许匿名访问的地址,写在最前边
.requestMatchers("/hello").permitAll()
//其他请求必须认证才能访问
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
HttpUtil.writeResponse(response, R.ok("未登录"));
}
})
.and()
//登录表单配置
.formLogin()
//登录表单的用户名name
// .usernameParameter("username")
//登录表单的密码name
// .passwordParameter("password")
.and()
.logout()
//退出登录的url
// .logoutUrl("/logout")
.logoutSuccessHandler(new LogoutHandler())
//清除session
// .invalidateHttpSession(true)
//清除认证信息
// .clearAuthentication(true)
.and()
//关闭csrf
.csrf().disable()
//添加自定义过滤器
.addFilterAt(myJsonLoginFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
// @Bean
// public InMemoryUserDetailsManager userDetailsService() {
// UserDetails user = User.withDefaultPasswordEncoder()
// .username("aaa")
// .password("111aaa")
// .roles("USER")
// .build();
// return new InMemoryUserDetailsManager(user);
// }
// @Bean
// public PasswordEncoder passwordEncoder() {
// return new MyPasswordEncoder();
// }
@Bean
JsonLoginFilter myJsonLoginFilter() throws Exception {
JsonLoginFilter myJsonLoginFilter = new JsonLoginFilter();
myJsonLoginFilter.setAuthenticationSuccessHandler(new LoginSuccessHandler());
myJsonLoginFilter.setAuthenticationFailureHandler(new LoginFailureHandler());
myJsonLoginFilter.setAuthenticationManager(authenticationManager());
return myJsonLoginFilter;
}
@Bean
AuthenticationManager authenticationManager(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
//设置用户信息处理器
daoAuthenticationProvider.setUserDetailsService(userDetailService);
//设置密码处理器
daoAuthenticationProvider.setPasswordEncoder(new MyPasswordEncoder());
ProviderManager pm = new ProviderManager(daoAuthenticationProvider);
return pm;
}
}
git地址:https://gitee.com/guan0207/puyu
但是登录成功后,还是未登录状态,SecurityContextHolder.getContext().getAuthentication().getPrincipal()取出来是anonymousUser是咋回事?