在使用security的过程中,我们会遇到未登录,用户名密码错误等等被拦截的情况。
这时系统的返回的都是跳转到登录页面,在实际使用中,我们更多的会是自定义登录页面,遇到异常情况,会根据返回结果进行“您的登录已过期”,“用户名或密码不正确”等提示。
这次我们来自定义返回信息。
首先第一个是登录成功的handle
package com.mu.security3.security.handle;
import com.alibaba.fastjson.JSON;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 登录成功时调用
*/
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
Map<String, Object> responseData = new HashMap<>();
responseData.put("status", 200);
responseData.put("msg", "登录成功!");
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setStatus(200);
httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
}
}
登录失败时的handle
package com.mu.security3.security.handle;
import com.alibaba.fastjson.JSON;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 登录失败时调用
*/
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException exception) throws IOException, ServletException {
Map<String, Object> responseData = new HashMap<>();
if (exception instanceof UsernameNotFoundException) {//此异常不会抛出,会被捕捉然后抛出为BadCredentialsException
responseData.put("status", 7001);
responseData.put("msg", "用户不存在!");
} else if (exception instanceof BadCredentialsException) {
responseData.put("status", 7002);
responseData.put("msg", "用户名或密码错误!");
} else if (exception instanceof LockedException) {
responseData.put("status", 7003);
responseData.put("msg", "用户已被锁定!");
} else if (exception instanceof DisabledException) {
responseData.put("status", 7004);
responseData.put("msg", "用户不可用!");
} else if (exception instanceof AccountExpiredException) {
responseData.put("status", 7005);
responseData.put("msg", "账户已过期!");
} else if (exception instanceof CredentialsExpiredException) {
responseData.put("status", 7006);
responseData.put("msg", "用户密码已过期!");
} else {
responseData.put("status", 7000);
responseData.put("msg", "认证失败,请联系网站管理员!");
}
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setStatus(200);
httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
}
}
未登录时的handle
package com.mu.security3.security.handle;
import com.alibaba.fastjson.JSON;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 未登录
*/
@Component
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
Map<String, Object> responseData = new HashMap<>();
responseData.put("status", 6001);
responseData.put("msg", "请登录");
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setStatus(200);
httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
}
}
配置文件
package com.mu.security3.security;
import com.mu.security3.security.handle.MyAuthenticationEntryPoint;
import com.mu.security3.security.handle.MyAuthenticationFailureHandler;
import com.mu.security3.security.handle.MyAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
MyUserDetailsService userDetailsService;
@Autowired
private MyAuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
MyAuthenticationFailureHandler authenticationFailureHandler;
@Autowired
MyAuthenticationEntryPoint authenticationEntryPoint;
/**
* 需要放行的URL
*/
private static final String[] AUTH_WHITELIST = {
"/ok/**"
};
// 配置 URL 访问权限
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 开启 HttpSecurity 配置
.antMatchers(AUTH_WHITELIST).permitAll().anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问)
.and().httpBasic().authenticationEntryPoint(authenticationEntryPoint)//未登录的情况下调用
.and().formLogin() // 开启表单登录
.successHandler(authenticationSuccessHandler)//登录成功handle
.failureHandler(authenticationFailureHandler)//登录失败handle
.permitAll()
.and().csrf().disable(); // 关闭csrf
}
// 配置用户及其对应的角色
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
//指定密码的加密方式
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.35</version>
<scope>compile</scope>
</dependency>
测试一下,ok接口
测试一下,需要验证的用户列表接口
测试一下,用户名不存在登录失败的情况
测试一下,登录成功
本篇记录就到此结束了,如果本篇文章对您有所帮助可以点个赞发个评论,不胜感激。如果内容有不对的地方或者有侵犯权益的地方也欢迎留言联系我。
源码地址
https://gitee.com/zhangxin2048/security
附参考博客
springboot security 自定义返回结果
https://blog.csdn.net/qq_27081015/article/details/103714367