浏览器中输入http://localhost:8080/test.html,认证服务跳转到login.html,输入正确的账号密码后,跳转过去返回404。
pom主要信息
spring boot version 2.0.4.RELEASE
spring security 、MVC version 2.0.4.RELEASE
仔细看了最后跳转的路径,是根路径“\”,和初衷test.html天壤之别。
@Component("mSuccessHandler")
public class CustomAuthenticationSuccesstHandler extends SimpleUrlAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request
, HttpServletResponse response
, Authentication authentication)
throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
查看源码super.OnAuthenticationSuccess(request,response,authentication);
public class SimpleUrlAuthenticationSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler implements AuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
this.handle(request, response, authentication);
this.clearAuthenticationAttributes(request);
}
}
继续this.handle(request,response,authentication);
public abstract class AbstractAuthenticationTargetUrlRequestHandler {
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
String targetUrl = this.determineTargetUrl(request, response);
if (response.isCommitted()) {
this.logger.debug("Response has already been committed. Unable to redirect to " + targetUrl);
} else {
this.redirectStrategy.sendRedirect(request, response, targetUrl);
}
}
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
if (this.isAlwaysUseDefaultTargetUrl()) {
return this.defaultTargetUrl;
} else {
String targetUrl = null;
if (this.targetUrlParameter != null) {
targetUrl = request.getParameter(this.targetUrlParameter);
if (StringUtils.hasText(targetUrl)) {
this.logger.debug("Found targetUrlParameter in request: " + targetUrl);
return targetUrl;
}
}
if (this.useReferer && !StringUtils.hasLength(targetUrl)) {
targetUrl = request.getHeader("Referer");
this.logger.debug("Using Referer header: " + targetUrl);
}
if (!StringUtils.hasText(targetUrl)) {
targetUrl = this.defaultTargetUrl;
this.logger.debug("Using default Url: " + targetUrl);
}
return targetUrl;
}
}
}
继续 this.determineTargetUrl(request, response);
target有三种被修改的可能方式:
1.targetUrlParameter不等于空
targetUrlParameter这是个成员属性,可以通过public void setTargetUrlParameter(String targetUrlParameter) {......}设置,而后targetUrl = request.getParameter(this.targetUrlParameter);
那么如何处理才能得到这个tergetUri呢?requestParameter该方法就是根据http上传的参数,而后获取其值。这里我本想通过request设置其值,但是request不支持setParameter这个方法,个人猜想也是为了保护该次请求唯一性吧。
假设可以通过某些方式,成功添加了请求参数,除非约束了请求跳转的参数名字,否则
targetUrl = request.getParameter(this.targetUrlParameter); 这个this.targetUriParameter也是个棘手的事情。
2. targetUrl = request.getHeader("Referer");通过header.Refer
同前者一样,request不支持setHeader一些api。
3.targetUrl = this.defaultTargetUrl;
前两种情况都为空的时候,只能使用默认的Uri,也就是跳转后报404的结果的路径“\”。
package com.fosun.springsecurity.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fosun.springsecurity.properties.LoginType;
import com.fosun.springsecurity.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.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author: Christ
* @date: 2018/8/16 11:18
* @desc:
*/
@Component("mAuthSuccessHandler")
public class CustomerAuthenticationSuccessRedirectHandler extends SimpleUrlAuthenticationSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomerAuthenticationSuccessRedirectHandler.class);
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request
, HttpServletResponse response
, Authentication authentication)
throws IOException, ServletException {
logger.info("登录成功");
if(securityProperties.getBrowser().getLoginType() == LoginType.JSON){
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
}else{
SavedRequest savedRequest = requestCache.getRequest(request,response);
String targetUrl = savedRequest.getRedirectUrl();
getRedirectStrategy().sendRedirect(request,response,targetUrl);
clearAuthenticationAttributes(request);
}
}
}
如果哪位同行有更好的建议和方法,还望不吝赐教。