记录下如何将oauth2的参数转存到/login请求上

需求:/oauth/authorize请求除标准参数外,有自定义参数,这些参数要用在spring security认证流程中,UserDetailsService的实现有多个,要根据自定义参数来区分

框架:spring-cloud-starter-oauth2,jwt

要解决的问题:1.LoginUrlAuthenticationEntryPoint.buildRedirectUrlToLoginPage方法返回的重定向url没有加queryString,2.生成默认登录页面的过滤器的url匹配是全路径匹配,会包含queryString,3.UsernamePasswordAuthenticationFilter中使用的WebAuthenticationDetailsSource只处理了remoteAddress和sessionId两个参数,没有处理自定义参数

实现:1.自定义CustomLoginUrlAuthenticationEntryPoint,代码如下

package org.liu.auth.entrypoint;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.RedirectUrlBuilder;
import org.springframework.security.web.util.UrlUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拒绝访问时redirect到登录url的entryPoint
 *
 * @Author lzs
 * @Date 2022/8/18 10:19
 **/
@Slf4j
public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    public CustomLoginUrlAuthenticationEntryPoint() {
        this("/login");
    }

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

    @Override
    protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
        String loginForm = determineUrlToUseForThisRequest(request, response,
                authException);

        if (UrlUtils.isAbsoluteUrl(loginForm)) {
            return loginForm;
        }

        int serverPort = super.getPortResolver().getServerPort(request);
        String scheme = request.getScheme();

        RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();

        urlBuilder.setScheme(scheme);
        urlBuilder.setServerName(request.getServerName());
        urlBuilder.setPort(serverPort);
        urlBuilder.setContextPath(request.getContextPath());
        urlBuilder.setPathInfo(loginForm);
        urlBuilder.setQuery(request.getQueryString());

        if (super.isForceHttps() && "http".equals(scheme)) {
            Integer httpsPort = super.getPortMapper().lookupHttpsPort(serverPort);

            if (httpsPort != null) {
                // Overwrite scheme and port in the redirect URL
                urlBuilder.setScheme("https");
                urlBuilder.setPort(httpsPort);
            } else {
                log.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port "
                        + serverPort);
            }
        }

        return urlBuilder.getUrl();
    }
}

2.自定义CustomDefaultLoginPageGeneratingFilter,CustomDefaultLoginPageConfigurer

package org.liu.auth.filter;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
import org.springframework.util.Assert;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;

/**
 * 重写了DefaultLoginPageGeneratingFilter,只是修改了isLoginUrlRequest方法的判断逻辑
 *
 * @Author lzs
 * @Date 2022/8/19 8:43
 **/
public class CustomDefaultLoginPageGeneratingFilter extends GenericFilterBean {
    public static final String DEFAULT_LOGIN_PAGE_URL = "/login";
    public static final String ERROR_PARAMETER_NAME = "error";
    private String loginPageUrl;
    private String logoutSuccessUrl;
    private String failureUrl;
    private boolean formLoginEnabled;
    private boolean openIdEnabled;
    private boolean oauth2LoginEnabled;
    private boolean saml2LoginEnabled;
    private String authenticationUrl;
    private String usernameParameter;
    private String passwordParameter;
    private String rememberMeParameter;
    private String openIDauthenticationUrl;
    private String openIDusernameParameter;
    private String openIDrememberMeParameter;
    private Map<String, String> oauth2AuthenticationUrlToClientName;
    private Map<String, String> saml2AuthenticationUrlToProviderName;
    private Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs = request -> Collections
            .emptyMap();


    public CustomDefaultLoginPageGeneratingFilter() {
    }

    public CustomDefaultLoginPageGeneratingFilter(AbstractAuthenticationProcessingFilter filter) {
        if (filter instanceof UsernamePasswordAuthenticationFilter) {
            init((UsernamePasswordAuthenticationFilter) filter, null);
        } else {
            init(null, filter);
        }
    }

    public CustomDefaultLoginPageGeneratingFilter(
            UsernamePasswordAuthenticationFilter authFilter,
            AbstractAuthenticationProcessingFilter openIDFilter) {
        init(authFilter, openIDFilter);
    }

    private void init(UsernamePasswordAuthenticationFilter authFilter,
                      AbstractAuthenticationProcessingFilter openIDFilter) {
        this.loginPageUrl = DEFAULT_LOGIN_PAGE_URL;
        this.logoutSuccessUrl = DEFAULT_LOGIN_PAGE_URL + "?logout";
        this.failureUrl = DEFAULT_LOGIN_PAGE_URL + "?" + ERROR_PARAMETER_NAME;
        if (authFilter != null) {
            formLoginEnabled = true;
            usernameParameter = authFilter.getUsernameParameter();
            passwordParameter = authFilter.getPasswordParameter();

            if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
                rememberMeParameter = ((AbstractRememberMeServices) authFilter
                        .getRememberMeServices()).getParameter();
            }
        }

        if (openIDFilter != null) {
            openIdEnabled = true;
            openIDusernameParameter = "openid_identifier";

            if (openIDFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
                openIDrememberMeParameter = ((AbstractRememberMeServices) openIDFilter
                        .getRememberMeServices()).getParameter();
            }
        }
    }

    /**
     * Sets a Function used to resolve a Map of the hidden inputs where the key is the
     * name of the input and the value is the value of the input. Typically this is used
     * to resolve the CSRF token.
     *
     * @param resolveHiddenInputs the function to resolve the inputs
     */
    public void setResolveHiddenInputs(
            Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs) {
        Assert.notNull(resolveHiddenInputs, "resolveHiddenInputs cannot be null");
        this.resolveHiddenInputs = resolveHiddenInputs;
    }

    public boolean isEnabled() {
        return formLoginEnabled || openIdEnabled || oauth2LoginEnabled || this.saml2LoginEnabled;
    }

    public void setLogoutSuccessUrl(String logoutSuccessUrl) {
        this.logoutSuccessUrl = logoutSuccessUrl;
    }

    public String getLoginPageUrl() {
        return loginPageUrl;
    }

    public void setLoginPageUrl(String loginPageUrl) {
        this.loginPageUrl = loginPageUrl;
    }

    public void setFailureUrl(String failureUrl) {
        this.failureUrl = failureUrl;
    }

    public void setFormLoginEnabled(boolean formLoginEnabled) {
        this.formLoginEnabled = formLoginEnabled;
    }

    public void setOpenIdEnabled(boolean openIdEnabled) {
        this.openIdEnabled = openIdEnabled;
    }

    public void setOauth2LoginEnabled(boolean oauth2LoginEnabled) {
        this.oauth2LoginEnabled = oauth2LoginEnabled;
    }

    public void setSaml2LoginEnabled(boolean saml2LoginEnabled) {
        this.saml2LoginEnabled = saml2LoginEnabled;
    }

    public void setAuthenticationUrl(String authenticationUrl) {
        this.authenticationUrl = authenticationUrl;
    }

    public void setUsernameParameter(String usernameParameter) {
        this.usernameParameter = usernameParameter;
    }

    public void setPasswordParameter(String passwordParameter) {
        this.passwordParameter = passwordParameter;
    }

    public void setRememberMeParameter(String rememberMeParameter) {
        this.rememberMeParameter = rememberMeParameter;
        this.openIDrememberMeParameter = rememberMeParameter;
    }

    public void setOpenIDauthenticationUrl(String openIDauthenticationUrl) {
        this.openIDauthenticationUrl = openIDauthenticationUrl;
    }

    public void setOpenIDusernameParameter(String openIDusernameParameter) {
        this.openIDusernameParameter = openIDusernameParameter;
    }

    public void setOauth2AuthenticationUrlToClientName(Map<String, String> oauth2AuthenticationUrlToClientName) {
        this.oauth2AuthenticationUrlToClientName = oauth2AuthenticationUrlToClientName;
    }

    public void setSaml2AuthenticationUrlToProviderName(Map<String, String> saml2AuthenticationUrlToProviderName) {
        this.saml2AuthenticationUrlToProviderName = saml2AuthenticationUrlToProviderName;
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        boolean loginError = isErrorPage(request);
        boolean logoutSuccess = isLogoutSuccess(request);
        if (isLoginUrlRequest(request) || loginError || logoutSuccess) {
            String loginPageHtml = generateLoginPageHtml(request, loginError,
                    logoutSuccess);
            response.setContentType("text/html;charset=UTF-8");
            response.setContentLength(loginPageHtml.getBytes(StandardCharsets.UTF_8).length);
            response.getWriter().write(loginPageHtml);

            return;
        }

        chain.doFilter(request, response);
    }

    private String generateLoginPageHtml(HttpServletRequest request, boolean loginError,
                                         boolean logoutSuccess) {
        String errorMsg = "Invalid credentials";

        if (loginError) {
            HttpSession session = request.getSession(false);

            if (session != null) {
                AuthenticationException ex = (AuthenticationException) session
                        .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
                errorMsg = ex != null ? ex.getMessage() : "Invalid credentials";
            }
        }

        StringBuilder sb = new StringBuilder();

        sb.append("<!DOCTYPE html>\n"
                + "<html lang=\"en\">\n"
                + "  <head>\n"
                + "    <meta charset=\"utf-8\">\n"
                + "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
                + "    <meta name=\"description\" content=\"\">\n"
                + "    <meta name=\"author\" content=\"\">\n"
                + "    <title>Please sign in</title>\n"
                + "    <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
                + "    <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
                + "  </head>\n"
                + "  <body>\n"
                + "     <div class=\"container\">\n");

        String contextPath = request.getContextPath();
        if (this.formLoginEnabled) {
            sb.append("      <form class=\"form-signin\" method=\"post\" action=\"" + contextPath + this.authenticationUrl + "\">\n"
                    + "        <h2 class=\"form-signin-heading\">Please sign in</h2>\n"
                    + createError(loginError, errorMsg)
                    + createLogoutSuccess(logoutSuccess)
                    + "        <p>\n"
                    + "          <label for=\"username\" class=\"sr-only\">Username</label>\n"
                    + "          <input type=\"text\" id=\"username\" name=\"" + this.usernameParameter + "\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
                    + "        </p>\n"
                    + "        <p>\n"
                    + "          <label for=\"password\" class=\"sr-only\">Password</label>\n"
                    + "          <input type=\"password\" id=\"password\" name=\"" + this.passwordParameter + "\" class=\"form-control\" placeholder=\"Password\" required>\n"
                    + "        </p>\n"
                    + createRememberMe(this.rememberMeParameter)
                    + renderHiddenInputs(request)
                    + "        <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
                    + "      </form>\n");
        }

        if (openIdEnabled) {
            sb.append("      <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"" + contextPath + this.openIDauthenticationUrl + "\">\n"
                    + "        <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n"
                    + createError(loginError, errorMsg)
                    + createLogoutSuccess(logoutSuccess)
                    + "        <p>\n"
                    + "          <label for=\"username\" class=\"sr-only\">Identity</label>\n"
                    + "          <input type=\"text\" id=\"username\" name=\"" + this.openIDusernameParameter + "\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
                    + "        </p>\n"
                    + createRememberMe(this.openIDrememberMeParameter)
                    + renderHiddenInputs(request)
                    + "        <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
                    + "      </form>\n");
        }

        if (oauth2LoginEnabled) {
            sb.append("<h2 class=\"form-signin-heading\">Login with OAuth 2.0</h2>");
            sb.append(createError(loginError, errorMsg));
            sb.append(createLogoutSuccess(logoutSuccess));
            sb.append("<table class=\"table table-striped\">\n");
            for (Map.Entry<String, String> clientAuthenticationUrlToClientName : oauth2AuthenticationUrlToClientName.entrySet()) {
                sb.append(" <tr><td>");
                String url = clientAuthenticationUrlToClientName.getKey();
                sb.append("<a href=\"").append(contextPath).append(url).append("\">");
                String clientName = HtmlUtils.htmlEscape(clientAuthenticationUrlToClientName.getValue());
                sb.append(clientName);
                sb.append("</a>");
                sb.append("</td></tr>\n");
            }
            sb.append("</table>\n");
        }

        if (this.saml2LoginEnabled) {
            sb.append("<h2 class=\"form-signin-heading\">Login with SAML 2.0</h2>");
            sb.append(createError(loginError, errorMsg));
            sb.append(createLogoutSuccess(logoutSuccess));
            sb.append("<table class=\"table table-striped\">\n");
            for (Map.Entry<String, String> relyingPartyUrlToName : saml2AuthenticationUrlToProviderName.entrySet()) {
                sb.append(" <tr><td>");
                String url = relyingPartyUrlToName.getKey();
                sb.append("<a href=\"").append(contextPath).append(url).append("\">");
                String partyName = HtmlUtils.htmlEscape(relyingPartyUrlToName.getValue());
                sb.append(partyName);
                sb.append("</a>");
                sb.append("</td></tr>\n");
            }
            sb.append("</table>\n");
        }
        sb.append("</div>\n");
        sb.append("</body></html>");

        return sb.toString();
    }

    private String renderHiddenInputs(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> input : this.resolveHiddenInputs.apply(request).entrySet()) {
            sb.append("<input name=\"").append(input.getKey()).append("\" type=\"hidden\" value=\"").append(input.getValue()).append("\" />\n");
        }
        return sb.toString();
    }

    private String createRememberMe(String paramName) {
        if (paramName == null) {
            return "";
        }
        return "<p><input type='checkbox' name='"
                + paramName
                + "'/> Remember me on this computer.</p>\n";
    }

    private boolean isLogoutSuccess(HttpServletRequest request) {
        return logoutSuccessUrl != null && matches(request, logoutSuccessUrl);
    }

    /**
     * change this method only
     *
     * @param request
     * @return
     */
    private boolean isLoginUrlRequest(HttpServletRequest request) {
        return matchesUri(request, loginPageUrl);
    }

    private boolean isErrorPage(HttpServletRequest request) {
        return matches(request, failureUrl);
    }

    private static String createError(boolean isError, String message) {
        return isError ? "<div class=\"alert alert-danger\" role=\"alert\">" + HtmlUtils.htmlEscape(message) + "</div>" : "";
    }

    private static String createLogoutSuccess(boolean isLogoutSuccess) {
        return isLogoutSuccess ? "<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div>" : "";
    }

    private boolean matchesUri(HttpServletRequest request, String url) {
        if (!"GET".equals(request.getMethod()) || url == null) {
            return false;
        }
        String uri = request.getRequestURI();
        int pathParamIndex = uri.indexOf(';');

        if (pathParamIndex > 0) {
            // strip everything after the first semi-colon
            uri = uri.substring(0, pathParamIndex);
        }
        if ("".equals(request.getContextPath())) {
            return uri.equals(url);
        }

        return uri.equals(request.getContextPath() + url);
    }

    private boolean matches(HttpServletRequest request, String url) {
        if (!"GET".equals(request.getMethod()) || url == null) {
            return false;
        }
        String uri = request.getRequestURI();
        int pathParamIndex = uri.indexOf(';');

        if (pathParamIndex > 0) {
            // strip everything after the first semi-colon
            uri = uri.substring(0, pathParamIndex);
        }

        if (request.getQueryString() != null) {
            uri += "?" + request.getQueryString();
        }

        if ("".equals(request.getContextPath())) {
            return uri.equals(url);
        }

        return uri.equals(request.getContextPath() + url);
    }
}
package org.liu.auth.configurer;

import org.liu.auth.filter.CustomDefaultLoginPageGeneratingFilter;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.DefaultLoginPageConfigurer;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
import org.springframework.security.web.csrf.CsrfToken;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * 自定义默认登陆页面的配置
 *
 * @Author lzs
 * @Date 2022/8/18 17:24
 **/
public class CustomDefaultLoginPageConfigurer<H extends HttpSecurityBuilder<H>> extends
        AbstractHttpConfigurer<DefaultLoginPageConfigurer<H>, H> {

    private CustomDefaultLoginPageGeneratingFilter loginPageGeneratingFilterFilter = new CustomDefaultLoginPageGeneratingFilter();
    private DefaultLogoutPageGeneratingFilter logoutPageGeneratingFilter = new DefaultLogoutPageGeneratingFilter();

    @Override
    public void init(H http) {
        initDefaultLoginFilter(http);
        initDefaultLogoutFilter(http);
    }

    @Override
    public void configure(H http) {
        if (loginPageGeneratingFilterFilter.isEnabled()) {
            loginPageGeneratingFilterFilter = postProcess(loginPageGeneratingFilterFilter);
            http.addFilterAfter(loginPageGeneratingFilterFilter, UsernamePasswordAuthenticationFilter.class);
            http.addFilter(this.logoutPageGeneratingFilter);
        }
    }

    private void initDefaultLoginFilter(H http) {
        Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs = request -> {
            Map<String, String> map = new HashMap<>();
            CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
            if (token != null) {
                map.put(token.getParameterName(), token.getToken());
            }
            Enumeration<String> parameterNames = request.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String paramName = parameterNames.nextElement();
                String paramValue = request.getParameter(paramName);
                map.put(paramName, paramValue);
            }
            return map;
        };
        loginPageGeneratingFilterFilter.setFormLoginEnabled(true);
        loginPageGeneratingFilterFilter.setUsernameParameter("username");
        loginPageGeneratingFilterFilter.setPasswordParameter("password");
        loginPageGeneratingFilterFilter.setLoginPageUrl("/login");
        loginPageGeneratingFilterFilter.setFailureUrl("/login?error");
        loginPageGeneratingFilterFilter.setAuthenticationUrl("/login");
        loginPageGeneratingFilterFilter.setResolveHiddenInputs(resolveHiddenInputs);
        http.setSharedObject(CustomDefaultLoginPageGeneratingFilter.class, loginPageGeneratingFilterFilter);
    }

    private void initDefaultLogoutFilter(H http) {
        Function<HttpServletRequest, Map<String, String>> hiddenInputs = request -> {
            CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
            if (token == null) {
                return Collections.emptyMap();
            }
            return Collections.singletonMap(token.getParameterName(), token.getToken());
        };
        this.logoutPageGeneratingFilter.setResolveHiddenInputs(hiddenInputs);
        http.setSharedObject(DefaultLogoutPageGeneratingFilter.class,
                logoutPageGeneratingFilter);
    }

}

3.自定义CustomWebAuthenticationDetailsSource,CustomWebAuthenticationDetails

package org.liu.auth.authentication;

import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

import static org.liu.common.core.constants.CommonConstants.HEADER_CLIENT;
import static org.liu.common.core.constants.CommonConstants.HEADER_TENANT_ID;

/**
 * @Author lzs
 * @Date 2022/8/15 16:15
 **/
public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, CustomWebAuthenticationDetails> {

    private RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public CustomWebAuthenticationDetails buildDetails(HttpServletRequest context) {
        String client = context.getHeader(HEADER_CLIENT);
        if (!StringUtils.hasText(client)) {
            client = context.getParameter(HEADER_CLIENT);
        }
        Long tenantId = null;
        String tenantIdStr = context.getHeader(HEADER_TENANT_ID);
        if (StringUtils.hasText(tenantIdStr)) {
            tenantId = Long.parseLong(tenantIdStr);
        } else {
            tenantIdStr = context.getParameter(HEADER_TENANT_ID);
            if (StringUtils.hasText(tenantIdStr)) {
                tenantId = Long.parseLong(tenantIdStr);
            }
        }
        return new CustomWebAuthenticationDetails(context, client, tenantId);
    }
}
package org.liu.auth.authentication;

import lombok.Getter;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author lzs
 * @Date 2022/8/15 16:17
 **/
@Getter
public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {

    private final String client;
    private final Long tenantId;

    public CustomWebAuthenticationDetails(HttpServletRequest request, String client, Long tenantId) {
        super(request);
        this.client = client;
        this.tenantId = tenantId;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof CustomWebAuthenticationDetails) {
            CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) obj;
            if (null != client && null == details.getClient()) {
                return false;
            }
            if (null == client && null != details.getClient()) {
                return false;
            }
            if (null != client && !client.equals(details.getClient())) {
                return false;
            }

            if (null != tenantId && null == details.getTenantId()) {
                return false;
            }
            if (null == tenantId && null != details.getTenantId()) {
                return false;
            }
            if (null != tenantId && tenantId.equals(details.getTenantId())) {
                return false;
            }
        } else {
            return false;
        }
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        int code = super.hashCode();
        if (null != client) {
            code = code * (this.client.hashCode() % 7);
        }
        if (null != tenantId) {
            code = code * (this.tenantId.hashCode() % 7);
        }
        return code;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(super.toString()).append(": ");
        sb.append("client: ").append(this.getClient()).append("; ");
        sb.append("tenantId: ").append(this.getTenantId());

        return sb.toString();
    }
}

4.把上面自定义的配置添加到httpSecurity中

http.formLogin().authenticationDetailsSource(customWebAuthenticationDetailsSource);
http.exceptionHandling().authenticationEntryPoint(customLoginUrlAuthenticationEntryPoint);
http.removeConfigurer(DefaultLoginPageConfigurer.class);
http.apply(new CustomDefaultLoginPageConfigurer<>());

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值