Security 自定义登录过滤器

通过 Security 实现登录自定义参数和Json请求方式

UsernamePasswordAuthenticationFilter 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private boolean postOnly = true;

// ~ Constructors
// ===================================================================================================

public UsernamePasswordAuthenticationFilter() {
super(new AntPathRequestMatcher("/login", "POST"));
}

// ~ Methods
// ========================================================================================================

public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}

String username = obtainUsername(request);
String password = obtainPassword(request);

if (username == null) {
username = "";
}

if (password == null) {
password = "";
}

username = username.trim();

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);

// Allow subclasses to set the "details" property
setDetails(request, authRequest);

return this.getAuthenticationManager().authenticate(authRequest);
}

通过重写attemptAuthentication 实现自定义参数

新建自定义过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class UserLoginAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private static final Logger LOGGER = LoggerFactory.getLogger(UserAuthenticationManager.class);

@Reference(version = "1.0")
private UserService userService;

@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
System.out.println("UserLoginAuthenticationFilter --> attemptAuthentication");

if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
LoginRequest loginRequest = builderLoginRequest(request);
TeResponse resp = userService.login(loginRequest);
if (!resp.isStatus()) {
throw new BadCredentialsException(resp.getMessage()+"="+resp.getStatusCode());
}

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
loginRequest.getAccount(), BCrypt.hashpw(loginRequest.getPassword(), BCrypt.gensalt()));

setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}

/**
* 构造请求参数
**/
@SuppressWarnings("unchecked")
private LoginRequest builderLoginRequest(HttpServletRequest request){
if(request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
||request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)){
ObjectMapper mapper = new ObjectMapper();
try (InputStream is = request.getInputStream()){
Map<String,String> map = mapper.readValue(is, Map.class);
return getLoginRequest(map);
}catch (IOException e) {
LOGGER.error("builderLoginRequest error-->",e);
throw new BadCredentialsException("请求格式异常=1003");
}
}
else{
return getLoginRequest(request);
}
}

/**
* 构造请求参数
* application/x-www-form-urlencoded
**/
private LoginRequest getLoginRequest(HttpServletRequest request){
LoginRequest loginRequest = new LoginRequest();
loginRequest.setUuid(request.getParameter(USER_UUID_KEY));
loginRequest.setVerifyCode(request.getParameter(USER_VERIFY_CODE_KEY));
loginRequest.setAccount(request.getParameter(USER_ACCOUNT_KEY));
loginRequest.setPassword(request.getParameter(USER_PASSWORD_KEY));
return loginRequest;
}
/**
* 构造请求参数
* application/json
**/
private LoginRequest getLoginRequest(Map<String,String> parameters ){
LoginRequest loginRequest = new LoginRequest();
loginRequest.setUuid(parameters.get(USER_UUID_KEY));
loginRequest.setVerifyCode(parameters.get(USER_VERIFY_CODE_KEY));
loginRequest.setAccount(parameters.get(USER_ACCOUNT_KEY));
loginRequest.setPassword(parameters.get(USER_PASSWORD_KEY));
return loginRequest;
}

WebSecurityConfig 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

private static String[] pathArray = new String[]{
"/user/captcha/base64Code","/user/forget/password"
};

@Autowired
private UserAuthenticationManager userAuthenticationManager;

@Override
protected void configure(HttpSecurity http) throws Exception {

http.cors().configurationSource(getSource());
http.csrf().disable();

http.authorizeRequests()
.antMatchers(pathArray).permitAll()
.anyRequest().authenticated();
// 添加登录自定义过滤器
http.addFilterAt(userLoginAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);


http.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.logoutSuccessHandler(logoutSuccessHandler())
.permitAll();

http.exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint())
.accessDeniedHandler(accessDeniedHandler());
}

@Bean
UserLoginAuthenticationFilter userLoginAuthenticationFilter(){
UserLoginAuthenticationFilter filter = new UserLoginAuthenticationFilter();
filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/user/login", "POST"));
filter.setAuthenticationFailureHandler(failureHandler());
filter.setAuthenticationSuccessHandler(authSuccessHandler());
filter.setAuthenticationManager(userAuthenticationManager);
return filter;
}

private UrlBasedCorsConfigurationSource getSource() {
CorsConfiguration configuration = new CorsConfiguration();
String corsAllowedOrigins = "http://127.0.0.1:20880,http://127.0.0.1:20881";
configuration.setAllowedOrigins(Arrays.asList(corsAllowedOrigins.split(",")));
String corsAllowedMethod = "POST, GET, OPTIONS";
configuration.setAllowedMethods(Arrays.asList(corsAllowedMethod.split(",")));
configuration.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
String corsPath = "/**";
source.registerCorsConfiguration(corsPath, configuration);
return source;
}

@Override
public void configure(WebSecurity web) throws Exception {
web.securityInterceptor(new SecurityInterceptor());
}

@Bean
AuthenticationSuccessHandler authSuccessHandler() {
return new UserAuthenticationHandler();
}

@Bean
AuthenticationFailureHandler failureHandler() {
return new UserAuthenticationFailureHandler();
}

@Bean
LogoutSuccessHandler logoutSuccessHandler() {
return new UserLogoutSuccessHandler();
}

@Bean
AccessDeniedHandler accessDeniedHandler() {
return new UserAccessDeniedHandler();
}
}