关于前后端一体项目SpringSecurity框架登陆失效,HTTPS重定向登陆页面异常的问题

发布于:2024-04-30 ⋅ 阅读:(30) ⋅ 点赞:(0)

现有环境是基于SpringBoot 2.6.8,然后是前后台一体化的项目。

安全框架使用的是内置版本的SpringSecurity。

场景:用户登陆,系统重启导致用户的session失效。但前端并没有跳转到对应的登录页,在HTTP的环境下可以正常跳转,但在生产环境跳转失败,并报以下错误。

页面上异常信息如下:

这里看了部分的源码,发现SpringSecurtiy中有LoginUrlAuthenticationEntryPoint的内,有对应的配置。这里是配置登陆失败跳转的地方。

	/**
	 * Performs the redirect (or forward) to the login form URL.
	 */
	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {
		if (!this.useForward) {
			// redirect to login page. Use https if forceHttps true
			String redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);
			this.redirectStrategy.sendRedirect(request, response, redirectUrl);
			return;
		}
		String redirectUrl = null;
		if (this.forceHttps && "http".equals(request.getScheme())) {
			// First redirect the current request to HTTPS. When that request is received,
			// the forward to the login page will be used.
			redirectUrl = buildHttpsRedirectUrlForRequest(request);
		}
		if (redirectUrl != null) {
			this.redirectStrategy.sendRedirect(request, response, redirectUrl);
			return;
		}
		String loginForm = determineUrlToUseForThisRequest(request, response, authException);
		logger.debug(LogMessage.format("Server side forward to: %s", loginForm));
		RequestDispatcher dispatcher = request.getRequestDispatcher(loginForm);
		dispatcher.forward(request, response);
		return;
	}

所以解决方案就是,重写这个类,将请求强制改为HTTPS。

实现方案如下:

import cn.com.seecom.vnumber.common.Result;
import cn.com.seecom.vnumber.common.ResultEnum;
import cn.com.seecom.vnumber.utils.RequestUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author lvshiyu
 * @description: 重写登陆验证失效切面
 * @date 2024年03月13日 17:55
 */
public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
        super(loginFormUrl);
        setForceHttps(true);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        if (RequestUtil.isAjaxRequest(request)) {
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.getWriter().println(JSON.toJSON(new Result(ResultEnum.TOKEN_EXPIRED)));
            return;
        } else {
            super.commence(request, response, authException);
        }
    }
}

核心是setForceHttps方法

在config中配置对应的切面。

以上就解决了我的问题


网站公告

今日签到

点亮在社区的每一天
去签到