1.功能图
之前我们的请求是直接会跳到一个请求登录页面的Controller,然后跳到登录页面,现在我们的需求是判断一下请求的类型,然后跳转到自己的Controller.,然后处理返回不同的信息。
现将之前的一些在demo-lilly里面的配置沉淀到borwser包里面,但是在打包的时候报找不到Filter,z所以在依赖中加上
要实现这样的一个功能需要跳转前判断这个请求的类型,这里需要HttpSessionRequestCache这个类拿到当前缓存的请求,
接到Html请求以后是否需要身份认证的这个判断是Security做的,如果需要身份认证,他会做一个跳转,根据你loginPage的配置来决定你跳到哪里,但是在执行这个跳转之前,Spring Security用HttpSessionRequestCache把当前的请求缓存到这个类里面,所以我们可以根据这个类来拿当前请求的类型。
判断之后利用这个类RedirectStrategy做跳转,至于跳转的请求需要从配置中拿。
下面介绍如何封装系统配置
2.系统配置封装
系统配置类我们写到core包里面,
springboot 访问template资源必须经过控制器,如果想不经过控制器直接跳转,需要将资源放到静态文件夹下。但是thymeleaf放到静态资源文件下有一个问题,就是页面会出现中文乱码,由于是静态资源所以无法通过视图解析器的配置去改变这一问题,就算解决了,thymeleaf的标签在静态资源下回全部失效,所以这种办法不可取,我们需要采取第二种解决方式
首选先demo项目的自定义登录配置页面
封装系统配置的第一个类
封装系统配置的第二个类:
资源文件在:
使系统配置起作用:
注入即可使用:
需要注意的是需要加上Controller转换到视图,这个配置不能在starter包里面去做转换,因为用户可能需要在自定义页面上显示一些问题
3.登录成功处理
默认情况下security登录成功后会把请求转到引发操作的请求上,那么什么时候需要自定义登录成功的处理,比如说前端登录后仅仅只想拿到用户的信息去做处理,这个时候就需要自定义登录成功的处理流程。
自定义登录成功处理需要实现一个接口
然后加上这样一个配置:
4.登录失败处理
实现AuthenticationFailureHandler接口
但是我们的目标是要做一个可重用的认证模块,也就是说要包含返回json,和跳转登录的这两种情况。
5.认证完成返回JSON或跳转
实现的思路:首先security的默认的认证成功的处理类是SavedRequestAwareAuthenticationSuccessHandler,他一样是实现了AuthenticationSuccessHandler接口,我们只需要继承这个默认的,再判断一下类型,实现自己的就行了。
两种类型:
默认JSON处理
package org.lilly.browser.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.lilly.core.properties.LoginType;
import org.lilly.core.properties.SecurityProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* User: Mr.Wang
* Date: 2020/6/8
*/
@Component
public class LillyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException,
ServletException {
logger.info("登录成功");
if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));
} else {
super.onAuthenticationSuccess(httpServletRequest, httpServletResponse, authentication);
}
}
}
demo项目配置:
测试:
首先我配置登录的类型为JSON类型或者不配置,访问hello.html,会返回JSON
当我们配置登录的类型后,访问http://localhost:8080/preLogin.html
当然需要一个控制器来处理这个登录的请求,登录后会自动跳转到登录前的页面
常见问题:
重定向次数太多,是因为自定义请求的登录页面没有去security放权
配置类无法注入使用,是因为demo项目的包没有扫描到