1.自定义登录成功处理
什么需要自定义登录成功处理,因为登录行为不止只有一种,有可能是ajax请求,而默认的则是form提交跳转的行为,这个时候就不是我们想要的一种结果。
如果自定义登录成功之后的行为?只需要实现AuthenticationSuccessHandler接口
@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
@Autowired
private ObjectMapper objectMapper;
//登录成功之后会被调用
//Authentication用来封装我们的认证信息,包括发起认证请求里的认证信息(IP,Session,以及认证通过之后UserDetails的实现类的信息),
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
logger.info("登录成功");
//把authentication返回给前台
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
}
}
再修改BrowserSecurityConfig类的配置信息
访问请求:http://localhost:8080/sign.html ,登录成功之后,会把用户的信息全部返回
{
authorities: [
{
authority: "admin" //该用户的角色信息
}
],
details: {
remoteAddress: "0:0:0:0:0:0:0:1", //发起请求的IP
sessionId: null
},
authenticated: true,
principal: { //principal就是UserDetails的实现类里面的信息
username: "admin",
password: "$2a$10$WPv2.mXiAPEaOXjAHP9jYuLNfbGT1Nk99Ix2fn351gZGKeEPiOTQW",
accountNonExpired: true,
accountNonLocked: true,
credentialsNonExpired: true,
enabled: true,
authorities: [
{
authority: "admin"
}
]
},
credentials: null,
name: "admin"
}
1.自定义登录错误处理
实现AuthenticationFailureHandler接口
@Component("myAuthenticationFailHandler")
public class MyAuthenticationFailHandler implements AuthenticationFailureHandler {
private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationFailHandler.class);
@Autowired
private ObjectMapper objectMapper;
//AuthenticationException记录,用户名没找到,密码没匹配上等信息 认证过程中所有发生的错误
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
logger.info("登录失败");
//把exception返回给前台
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(exception));
}
}
同样也需要配置BrowserSecurityConfig配置类
访问请求:http://localhost:8080/sign.html ,登录失败之后,会把异常信息返回
2.可配置化
需要把它做成可配置化的,有些应用却是是form提交方式,应该需要更灵活一些
在BrowserProperties中定义一下跳转方式
public enum LoginType {
REDIRECT, //跳转
JSON; //JSON
}
public class BrowserProperties {
//标准的登录页面,如果其他项目没有配置则使用默认的登录配置
private String loginPage = "/sign.html";
private LoginType loginType = LoginType.JSON;//默认返回json
//get/set
}
既然需要跳转页面的这种方式,这个时候就不能仅仅实现Success/FailHandler接口这样了。
@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;//判断我们的请求数据的返回方式json/redirect
//登录成功之后会被调用
//Authentication用来封装我们的认证信息,包括发起认证请求里的认证信息(IP,Session,以及认证通过之后UserDetails的实现类的信息),
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
logger.info("登录成功");
if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
//把authentication返回给前台
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
}else {
//跳转
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
@Component("myAuthenticationFailHandler")
public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationFailHandler.class);
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
//AuthenticationException记录,用户名没找到,密码没匹配上等信息 认证过程中所有发生的错误
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
logger.info("登录失败");
if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
//把exception返回给前台
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(exception));
}else {
//跳转,即返回页面
super.onAuthenticationFailure(request, response, exception);
}
}
}
访问请求:http://localhost:8080/sign.html ,登录成功和失败都会返回json的方式
当更改完配置:
LoginType.REDIRECT;
再次访问请求:http://localhost:8080/sign.html ,登录成功和失败都会返回跳转的方式