当前位置:   article > 正文

记录下如何将oauth2的参数转存到/login请求上_oauth/authorize 跳到登录页过程

oauth/authorize 跳到登录页过程

需求:/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,代码如下

  1. package org.liu.auth.entrypoint;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.security.core.AuthenticationException;
  4. import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
  5. import org.springframework.security.web.util.RedirectUrlBuilder;
  6. import org.springframework.security.web.util.UrlUtils;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. /**
  10. * 自定义拒绝访问时redirect到登录url的entryPoint
  11. *
  12. * @Author lzs
  13. * @Date 2022/8/18 10:19
  14. **/
  15. @Slf4j
  16. public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
  17. public CustomLoginUrlAuthenticationEntryPoint() {
  18. this("/login");
  19. }
  20. public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
  21. super(loginFormUrl);
  22. }
  23. @Override
  24. protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
  25. String loginForm = determineUrlToUseForThisRequest(request, response,
  26. authException);
  27. if (UrlUtils.isAbsoluteUrl(loginForm)) {
  28. return loginForm;
  29. }
  30. int serverPort = super.getPortResolver().getServerPort(request);
  31. String scheme = request.getScheme();
  32. RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
  33. urlBuilder.setScheme(scheme);
  34. urlBuilder.setServerName(request.getServerName());
  35. urlBuilder.setPort(serverPort);
  36. urlBuilder.setContextPath(request.getContextPath());
  37. urlBuilder.setPathInfo(loginForm);
  38. urlBuilder.setQuery(request.getQueryString());
  39. if (super.isForceHttps() && "http".equals(scheme)) {
  40. Integer httpsPort = super.getPortMapper().lookupHttpsPort(serverPort);
  41. if (httpsPort != null) {
  42. // Overwrite scheme and port in the redirect URL
  43. urlBuilder.setScheme("https");
  44. urlBuilder.setPort(httpsPort);
  45. } else {
  46. log.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port "
  47. + serverPort);
  48. }
  49. }
  50. return urlBuilder.getUrl();
  51. }
  52. }

2.自定义CustomDefaultLoginPageGeneratingFilter,CustomDefaultLoginPageConfigurer

  1. package org.liu.auth.filter;
  2. import org.springframework.security.core.AuthenticationException;
  3. import org.springframework.security.web.WebAttributes;
  4. import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
  5. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  6. import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
  7. import org.springframework.util.Assert;
  8. import org.springframework.web.filter.GenericFilterBean;
  9. import org.springframework.web.util.HtmlUtils;
  10. import javax.servlet.FilterChain;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.ServletRequest;
  13. import javax.servlet.ServletResponse;
  14. import javax.servlet.http.HttpServletRequest;
  15. import javax.servlet.http.HttpServletResponse;
  16. import javax.servlet.http.HttpSession;
  17. import java.io.IOException;
  18. import java.nio.charset.StandardCharsets;
  19. import java.util.Collections;
  20. import java.util.Map;
  21. import java.util.function.Function;
  22. /**
  23. * 重写了DefaultLoginPageGeneratingFilter,只是修改了isLoginUrlRequest方法的判断逻辑
  24. *
  25. * @Author lzs
  26. * @Date 2022/8/19 8:43
  27. **/
  28. public class CustomDefaultLoginPageGeneratingFilter extends GenericFilterBean {
  29. public static final String DEFAULT_LOGIN_PAGE_URL = "/login";
  30. public static final String ERROR_PARAMETER_NAME = "error";
  31. private String loginPageUrl;
  32. private String logoutSuccessUrl;
  33. private String failureUrl;
  34. private boolean formLoginEnabled;
  35. private boolean openIdEnabled;
  36. private boolean oauth2LoginEnabled;
  37. private boolean saml2LoginEnabled;
  38. private String authenticationUrl;
  39. private String usernameParameter;
  40. private String passwordParameter;
  41. private String rememberMeParameter;
  42. private String openIDauthenticationUrl;
  43. private String openIDusernameParameter;
  44. private String openIDrememberMeParameter;
  45. private Map<String, String> oauth2AuthenticationUrlToClientName;
  46. private Map<String, String> saml2AuthenticationUrlToProviderName;
  47. private Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs = request -> Collections
  48. .emptyMap();
  49. public CustomDefaultLoginPageGeneratingFilter() {
  50. }
  51. public CustomDefaultLoginPageGeneratingFilter(AbstractAuthenticationProcessingFilter filter) {
  52. if (filter instanceof UsernamePasswordAuthenticationFilter) {
  53. init((UsernamePasswordAuthenticationFilter) filter, null);
  54. } else {
  55. init(null, filter);
  56. }
  57. }
  58. public CustomDefaultLoginPageGeneratingFilter(
  59. UsernamePasswordAuthenticationFilter authFilter,
  60. AbstractAuthenticationProcessingFilter openIDFilter) {
  61. init(authFilter, openIDFilter);
  62. }
  63. private void init(UsernamePasswordAuthenticationFilter authFilter,
  64. AbstractAuthenticationProcessingFilter openIDFilter) {
  65. this.loginPageUrl = DEFAULT_LOGIN_PAGE_URL;
  66. this.logoutSuccessUrl = DEFAULT_LOGIN_PAGE_URL + "?logout";
  67. this.failureUrl = DEFAULT_LOGIN_PAGE_URL + "?" + ERROR_PARAMETER_NAME;
  68. if (authFilter != null) {
  69. formLoginEnabled = true;
  70. usernameParameter = authFilter.getUsernameParameter();
  71. passwordParameter = authFilter.getPasswordParameter();
  72. if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
  73. rememberMeParameter = ((AbstractRememberMeServices) authFilter
  74. .getRememberMeServices()).getParameter();
  75. }
  76. }
  77. if (openIDFilter != null) {
  78. openIdEnabled = true;
  79. openIDusernameParameter = "openid_identifier";
  80. if (openIDFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
  81. openIDrememberMeParameter = ((AbstractRememberMeServices) openIDFilter
  82. .getRememberMeServices()).getParameter();
  83. }
  84. }
  85. }
  86. /**
  87. * Sets a Function used to resolve a Map of the hidden inputs where the key is the
  88. * name of the input and the value is the value of the input. Typically this is used
  89. * to resolve the CSRF token.
  90. *
  91. * @param resolveHiddenInputs the function to resolve the inputs
  92. */
  93. public void setResolveHiddenInputs(
  94. Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs) {
  95. Assert.notNull(resolveHiddenInputs, "resolveHiddenInputs cannot be null");
  96. this.resolveHiddenInputs = resolveHiddenInputs;
  97. }
  98. public boolean isEnabled() {
  99. return formLoginEnabled || openIdEnabled || oauth2LoginEnabled || this.saml2LoginEnabled;
  100. }
  101. public void setLogoutSuccessUrl(String logoutSuccessUrl) {
  102. this.logoutSuccessUrl = logoutSuccessUrl;
  103. }
  104. public String getLoginPageUrl() {
  105. return loginPageUrl;
  106. }
  107. public void setLoginPageUrl(String loginPageUrl) {
  108. this.loginPageUrl = loginPageUrl;
  109. }
  110. public void setFailureUrl(String failureUrl) {
  111. this.failureUrl = failureUrl;
  112. }
  113. public void setFormLoginEnabled(boolean formLoginEnabled) {
  114. this.formLoginEnabled = formLoginEnabled;
  115. }
  116. public void setOpenIdEnabled(boolean openIdEnabled) {
  117. this.openIdEnabled = openIdEnabled;
  118. }
  119. public void setOauth2LoginEnabled(boolean oauth2LoginEnabled) {
  120. this.oauth2LoginEnabled = oauth2LoginEnabled;
  121. }
  122. public void setSaml2LoginEnabled(boolean saml2LoginEnabled) {
  123. this.saml2LoginEnabled = saml2LoginEnabled;
  124. }
  125. public void setAuthenticationUrl(String authenticationUrl) {
  126. this.authenticationUrl = authenticationUrl;
  127. }
  128. public void setUsernameParameter(String usernameParameter) {
  129. this.usernameParameter = usernameParameter;
  130. }
  131. public void setPasswordParameter(String passwordParameter) {
  132. this.passwordParameter = passwordParameter;
  133. }
  134. public void setRememberMeParameter(String rememberMeParameter) {
  135. this.rememberMeParameter = rememberMeParameter;
  136. this.openIDrememberMeParameter = rememberMeParameter;
  137. }
  138. public void setOpenIDauthenticationUrl(String openIDauthenticationUrl) {
  139. this.openIDauthenticationUrl = openIDauthenticationUrl;
  140. }
  141. public void setOpenIDusernameParameter(String openIDusernameParameter) {
  142. this.openIDusernameParameter = openIDusernameParameter;
  143. }
  144. public void setOauth2AuthenticationUrlToClientName(Map<String, String> oauth2AuthenticationUrlToClientName) {
  145. this.oauth2AuthenticationUrlToClientName = oauth2AuthenticationUrlToClientName;
  146. }
  147. public void setSaml2AuthenticationUrlToProviderName(Map<String, String> saml2AuthenticationUrlToProviderName) {
  148. this.saml2AuthenticationUrlToProviderName = saml2AuthenticationUrlToProviderName;
  149. }
  150. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
  151. throws IOException, ServletException {
  152. HttpServletRequest request = (HttpServletRequest) req;
  153. HttpServletResponse response = (HttpServletResponse) res;
  154. boolean loginError = isErrorPage(request);
  155. boolean logoutSuccess = isLogoutSuccess(request);
  156. if (isLoginUrlRequest(request) || loginError || logoutSuccess) {
  157. String loginPageHtml = generateLoginPageHtml(request, loginError,
  158. logoutSuccess);
  159. response.setContentType("text/html;charset=UTF-8");
  160. response.setContentLength(loginPageHtml.getBytes(StandardCharsets.UTF_8).length);
  161. response.getWriter().write(loginPageHtml);
  162. return;
  163. }
  164. chain.doFilter(request, response);
  165. }
  166. private String generateLoginPageHtml(HttpServletRequest request, boolean loginError,
  167. boolean logoutSuccess) {
  168. String errorMsg = "Invalid credentials";
  169. if (loginError) {
  170. HttpSession session = request.getSession(false);
  171. if (session != null) {
  172. AuthenticationException ex = (AuthenticationException) session
  173. .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
  174. errorMsg = ex != null ? ex.getMessage() : "Invalid credentials";
  175. }
  176. }
  177. StringBuilder sb = new StringBuilder();
  178. sb.append("<!DOCTYPE html>\n"
  179. + "<html lang=\"en\">\n"
  180. + " <head>\n"
  181. + " <meta charset=\"utf-8\">\n"
  182. + " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
  183. + " <meta name=\"description\" content=\"\">\n"
  184. + " <meta name=\"author\" content=\"\">\n"
  185. + " <title>Please sign in</title>\n"
  186. + " <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"
  187. + " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
  188. + " </head>\n"
  189. + " <body>\n"
  190. + " <div class=\"container\">\n");
  191. String contextPath = request.getContextPath();
  192. if (this.formLoginEnabled) {
  193. sb.append(" <form class=\"form-signin\" method=\"post\" action=\"" + contextPath + this.authenticationUrl + "\">\n"
  194. + " <h2 class=\"form-signin-heading\">Please sign in</h2>\n"
  195. + createError(loginError, errorMsg)
  196. + createLogoutSuccess(logoutSuccess)
  197. + " <p>\n"
  198. + " <label for=\"username\" class=\"sr-only\">Username</label>\n"
  199. + " <input type=\"text\" id=\"username\" name=\"" + this.usernameParameter + "\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
  200. + " </p>\n"
  201. + " <p>\n"
  202. + " <label for=\"password\" class=\"sr-only\">Password</label>\n"
  203. + " <input type=\"password\" id=\"password\" name=\"" + this.passwordParameter + "\" class=\"form-control\" placeholder=\"Password\" required>\n"
  204. + " </p>\n"
  205. + createRememberMe(this.rememberMeParameter)
  206. + renderHiddenInputs(request)
  207. + " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
  208. + " </form>\n");
  209. }
  210. if (openIdEnabled) {
  211. sb.append(" <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"" + contextPath + this.openIDauthenticationUrl + "\">\n"
  212. + " <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n"
  213. + createError(loginError, errorMsg)
  214. + createLogoutSuccess(logoutSuccess)
  215. + " <p>\n"
  216. + " <label for=\"username\" class=\"sr-only\">Identity</label>\n"
  217. + " <input type=\"text\" id=\"username\" name=\"" + this.openIDusernameParameter + "\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
  218. + " </p>\n"
  219. + createRememberMe(this.openIDrememberMeParameter)
  220. + renderHiddenInputs(request)
  221. + " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
  222. + " </form>\n");
  223. }
  224. if (oauth2LoginEnabled) {
  225. sb.append("<h2 class=\"form-signin-heading\">Login with OAuth 2.0</h2>");
  226. sb.append(createError(loginError, errorMsg));
  227. sb.append(createLogoutSuccess(logoutSuccess));
  228. sb.append("<table class=\"table table-striped\">\n");
  229. for (Map.Entry<String, String> clientAuthenticationUrlToClientName : oauth2AuthenticationUrlToClientName.entrySet()) {
  230. sb.append(" <tr><td>");
  231. String url = clientAuthenticationUrlToClientName.getKey();
  232. sb.append("<a href=\"").append(contextPath).append(url).append("\">");
  233. String clientName = HtmlUtils.htmlEscape(clientAuthenticationUrlToClientName.getValue());
  234. sb.append(clientName);
  235. sb.append("</a>");
  236. sb.append("</td></tr>\n");
  237. }
  238. sb.append("</table>\n");
  239. }
  240. if (this.saml2LoginEnabled) {
  241. sb.append("<h2 class=\"form-signin-heading\">Login with SAML 2.0</h2>");
  242. sb.append(createError(loginError, errorMsg));
  243. sb.append(createLogoutSuccess(logoutSuccess));
  244. sb.append("<table class=\"table table-striped\">\n");
  245. for (Map.Entry<String, String> relyingPartyUrlToName : saml2AuthenticationUrlToProviderName.entrySet()) {
  246. sb.append(" <tr><td>");
  247. String url = relyingPartyUrlToName.getKey();
  248. sb.append("<a href=\"").append(contextPath).append(url).append("\">");
  249. String partyName = HtmlUtils.htmlEscape(relyingPartyUrlToName.getValue());
  250. sb.append(partyName);
  251. sb.append("</a>");
  252. sb.append("</td></tr>\n");
  253. }
  254. sb.append("</table>\n");
  255. }
  256. sb.append("</div>\n");
  257. sb.append("</body></html>");
  258. return sb.toString();
  259. }
  260. private String renderHiddenInputs(HttpServletRequest request) {
  261. StringBuilder sb = new StringBuilder();
  262. for (Map.Entry<String, String> input : this.resolveHiddenInputs.apply(request).entrySet()) {
  263. sb.append("<input name=\"").append(input.getKey()).append("\" type=\"hidden\" value=\"").append(input.getValue()).append("\" />\n");
  264. }
  265. return sb.toString();
  266. }
  267. private String createRememberMe(String paramName) {
  268. if (paramName == null) {
  269. return "";
  270. }
  271. return "<p><input type='checkbox' name='"
  272. + paramName
  273. + "'/> Remember me on this computer.</p>\n";
  274. }
  275. private boolean isLogoutSuccess(HttpServletRequest request) {
  276. return logoutSuccessUrl != null && matches(request, logoutSuccessUrl);
  277. }
  278. /**
  279. * change this method only
  280. *
  281. * @param request
  282. * @return
  283. */
  284. private boolean isLoginUrlRequest(HttpServletRequest request) {
  285. return matchesUri(request, loginPageUrl);
  286. }
  287. private boolean isErrorPage(HttpServletRequest request) {
  288. return matches(request, failureUrl);
  289. }
  290. private static String createError(boolean isError, String message) {
  291. return isError ? "<div class=\"alert alert-danger\" role=\"alert\">" + HtmlUtils.htmlEscape(message) + "</div>" : "";
  292. }
  293. private static String createLogoutSuccess(boolean isLogoutSuccess) {
  294. return isLogoutSuccess ? "<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div>" : "";
  295. }
  296. private boolean matchesUri(HttpServletRequest request, String url) {
  297. if (!"GET".equals(request.getMethod()) || url == null) {
  298. return false;
  299. }
  300. String uri = request.getRequestURI();
  301. int pathParamIndex = uri.indexOf(';');
  302. if (pathParamIndex > 0) {
  303. // strip everything after the first semi-colon
  304. uri = uri.substring(0, pathParamIndex);
  305. }
  306. if ("".equals(request.getContextPath())) {
  307. return uri.equals(url);
  308. }
  309. return uri.equals(request.getContextPath() + url);
  310. }
  311. private boolean matches(HttpServletRequest request, String url) {
  312. if (!"GET".equals(request.getMethod()) || url == null) {
  313. return false;
  314. }
  315. String uri = request.getRequestURI();
  316. int pathParamIndex = uri.indexOf(';');
  317. if (pathParamIndex > 0) {
  318. // strip everything after the first semi-colon
  319. uri = uri.substring(0, pathParamIndex);
  320. }
  321. if (request.getQueryString() != null) {
  322. uri += "?" + request.getQueryString();
  323. }
  324. if ("".equals(request.getContextPath())) {
  325. return uri.equals(url);
  326. }
  327. return uri.equals(request.getContextPath() + url);
  328. }
  329. }
  1. package org.liu.auth.configurer;
  2. import org.liu.auth.filter.CustomDefaultLoginPageGeneratingFilter;
  3. import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
  4. import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
  5. import org.springframework.security.config.annotation.web.configurers.DefaultLoginPageConfigurer;
  6. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  7. import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
  8. import org.springframework.security.web.csrf.CsrfToken;
  9. import javax.servlet.http.HttpServletRequest;
  10. import java.util.Collections;
  11. import java.util.Enumeration;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import java.util.function.Function;
  15. /**
  16. * 自定义默认登陆页面的配置
  17. *
  18. * @Author lzs
  19. * @Date 2022/8/18 17:24
  20. **/
  21. public class CustomDefaultLoginPageConfigurer<H extends HttpSecurityBuilder<H>> extends
  22. AbstractHttpConfigurer<DefaultLoginPageConfigurer<H>, H> {
  23. private CustomDefaultLoginPageGeneratingFilter loginPageGeneratingFilterFilter = new CustomDefaultLoginPageGeneratingFilter();
  24. private DefaultLogoutPageGeneratingFilter logoutPageGeneratingFilter = new DefaultLogoutPageGeneratingFilter();
  25. @Override
  26. public void init(H http) {
  27. initDefaultLoginFilter(http);
  28. initDefaultLogoutFilter(http);
  29. }
  30. @Override
  31. public void configure(H http) {
  32. if (loginPageGeneratingFilterFilter.isEnabled()) {
  33. loginPageGeneratingFilterFilter = postProcess(loginPageGeneratingFilterFilter);
  34. http.addFilterAfter(loginPageGeneratingFilterFilter, UsernamePasswordAuthenticationFilter.class);
  35. http.addFilter(this.logoutPageGeneratingFilter);
  36. }
  37. }
  38. private void initDefaultLoginFilter(H http) {
  39. Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs = request -> {
  40. Map<String, String> map = new HashMap<>();
  41. CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
  42. if (token != null) {
  43. map.put(token.getParameterName(), token.getToken());
  44. }
  45. Enumeration<String> parameterNames = request.getParameterNames();
  46. while (parameterNames.hasMoreElements()) {
  47. String paramName = parameterNames.nextElement();
  48. String paramValue = request.getParameter(paramName);
  49. map.put(paramName, paramValue);
  50. }
  51. return map;
  52. };
  53. loginPageGeneratingFilterFilter.setFormLoginEnabled(true);
  54. loginPageGeneratingFilterFilter.setUsernameParameter("username");
  55. loginPageGeneratingFilterFilter.setPasswordParameter("password");
  56. loginPageGeneratingFilterFilter.setLoginPageUrl("/login");
  57. loginPageGeneratingFilterFilter.setFailureUrl("/login?error");
  58. loginPageGeneratingFilterFilter.setAuthenticationUrl("/login");
  59. loginPageGeneratingFilterFilter.setResolveHiddenInputs(resolveHiddenInputs);
  60. http.setSharedObject(CustomDefaultLoginPageGeneratingFilter.class, loginPageGeneratingFilterFilter);
  61. }
  62. private void initDefaultLogoutFilter(H http) {
  63. Function<HttpServletRequest, Map<String, String>> hiddenInputs = request -> {
  64. CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
  65. if (token == null) {
  66. return Collections.emptyMap();
  67. }
  68. return Collections.singletonMap(token.getParameterName(), token.getToken());
  69. };
  70. this.logoutPageGeneratingFilter.setResolveHiddenInputs(hiddenInputs);
  71. http.setSharedObject(DefaultLogoutPageGeneratingFilter.class,
  72. logoutPageGeneratingFilter);
  73. }
  74. }

3.自定义CustomWebAuthenticationDetailsSource,CustomWebAuthenticationDetails

  1. package org.liu.auth.authentication;
  2. import org.springframework.security.authentication.AuthenticationDetailsSource;
  3. import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
  4. import org.springframework.security.web.savedrequest.RequestCache;
  5. import org.springframework.security.web.savedrequest.SavedRequest;
  6. import org.springframework.util.CollectionUtils;
  7. import org.springframework.util.StringUtils;
  8. import javax.servlet.http.HttpServletRequest;
  9. import java.util.List;
  10. import static org.liu.common.core.constants.CommonConstants.HEADER_CLIENT;
  11. import static org.liu.common.core.constants.CommonConstants.HEADER_TENANT_ID;
  12. /**
  13. * @Author lzs
  14. * @Date 2022/8/15 16:15
  15. **/
  16. public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, CustomWebAuthenticationDetails> {
  17. private RequestCache requestCache = new HttpSessionRequestCache();
  18. @Override
  19. public CustomWebAuthenticationDetails buildDetails(HttpServletRequest context) {
  20. String client = context.getHeader(HEADER_CLIENT);
  21. if (!StringUtils.hasText(client)) {
  22. client = context.getParameter(HEADER_CLIENT);
  23. }
  24. Long tenantId = null;
  25. String tenantIdStr = context.getHeader(HEADER_TENANT_ID);
  26. if (StringUtils.hasText(tenantIdStr)) {
  27. tenantId = Long.parseLong(tenantIdStr);
  28. } else {
  29. tenantIdStr = context.getParameter(HEADER_TENANT_ID);
  30. if (StringUtils.hasText(tenantIdStr)) {
  31. tenantId = Long.parseLong(tenantIdStr);
  32. }
  33. }
  34. return new CustomWebAuthenticationDetails(context, client, tenantId);
  35. }
  36. }
  1. package org.liu.auth.authentication;
  2. import lombok.Getter;
  3. import org.springframework.security.web.authentication.WebAuthenticationDetails;
  4. import javax.servlet.http.HttpServletRequest;
  5. /**
  6. * @Author lzs
  7. * @Date 2022/8/15 16:17
  8. **/
  9. @Getter
  10. public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
  11. private final String client;
  12. private final Long tenantId;
  13. public CustomWebAuthenticationDetails(HttpServletRequest request, String client, Long tenantId) {
  14. super(request);
  15. this.client = client;
  16. this.tenantId = tenantId;
  17. }
  18. @Override
  19. public boolean equals(Object obj) {
  20. if (obj instanceof CustomWebAuthenticationDetails) {
  21. CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) obj;
  22. if (null != client && null == details.getClient()) {
  23. return false;
  24. }
  25. if (null == client && null != details.getClient()) {
  26. return false;
  27. }
  28. if (null != client && !client.equals(details.getClient())) {
  29. return false;
  30. }
  31. if (null != tenantId && null == details.getTenantId()) {
  32. return false;
  33. }
  34. if (null == tenantId && null != details.getTenantId()) {
  35. return false;
  36. }
  37. if (null != tenantId && tenantId.equals(details.getTenantId())) {
  38. return false;
  39. }
  40. } else {
  41. return false;
  42. }
  43. return super.equals(obj);
  44. }
  45. @Override
  46. public int hashCode() {
  47. int code = super.hashCode();
  48. if (null != client) {
  49. code = code * (this.client.hashCode() % 7);
  50. }
  51. if (null != tenantId) {
  52. code = code * (this.tenantId.hashCode() % 7);
  53. }
  54. return code;
  55. }
  56. @Override
  57. public String toString() {
  58. StringBuilder sb = new StringBuilder();
  59. sb.append(super.toString()).append(": ");
  60. sb.append("client: ").append(this.getClient()).append("; ");
  61. sb.append("tenantId: ").append(this.getTenantId());
  62. return sb.toString();
  63. }
  64. }

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/84186
推荐阅读
相关标签
  

闽ICP备14008679号