SpringSecurity过滤器之DefaultLoginPageGeneratingFilter

发布时间 2023-05-02 15:11:56作者: shigp1

DefaultLoginPageGeneratingFilter用于生成默认登录页。

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	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);
}

generateLoginPageHtml生成登录页面。

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";
		}
	}
	String contextPath = request.getContextPath();
	StringBuilder sb = new StringBuilder();
	sb.append("<!DOCTYPE html>\n");
	sb.append("<html lang=\"en\">\n");
	sb.append("  <head>\n");
	sb.append("    <meta charset=\"utf-8\">\n");
	sb.append("    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n");
	sb.append("    <meta name=\"description\" content=\"\">\n");
	sb.append("    <meta name=\"author\" content=\"\">\n");
	sb.append("    <title>Please sign in</title>\n");
	sb.append("    <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");
	sb.append("    <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" "
			+ "rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n");
	sb.append("  </head>\n");
	sb.append("  <body>\n");
	sb.append("     <div class=\"container\">\n");
	if (this.formLoginEnabled) {
		sb.append("      <form class=\"form-signin\" method=\"post\" action=\"" + contextPath
				+ this.authenticationUrl + "\">\n");
		sb.append("        <h2 class=\"form-signin-heading\">Please sign in</h2>\n");
		sb.append(createError(loginError, errorMsg) + createLogoutSuccess(logoutSuccess) + "        <p>\n");
		sb.append("          <label for=\"username\" class=\"sr-only\">Username</label>\n");
		sb.append("          <input type=\"text\" id=\"username\" name=\"" + this.usernameParameter
				+ "\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n");
		sb.append("        </p>\n");
		sb.append("        <p>\n");
		sb.append("          <label for=\"password\" class=\"sr-only\">Password</label>\n");
		sb.append("          <input type=\"password\" id=\"password\" name=\"" + this.passwordParameter
				+ "\" class=\"form-control\" placeholder=\"Password\" required>\n");
		sb.append("        </p>\n");
		sb.append(createRememberMe(this.rememberMeParameter) + renderHiddenInputs(request));
		sb.append("        <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n");
		sb.append("      </form>\n");
	}
	if (this.openIdEnabled) {
		sb.append("      <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"" + contextPath
				+ this.openIDauthenticationUrl + "\">\n");
		sb.append("        <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n");
		sb.append(createError(loginError, errorMsg) + createLogoutSuccess(logoutSuccess) + "        <p>\n");
		sb.append("          <label for=\"username\" class=\"sr-only\">Identity</label>\n");
		sb.append("          <input type=\"text\" id=\"username\" name=\"" + this.openIDusernameParameter
				+ "\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n");
		sb.append("        </p>\n");
		sb.append(createRememberMe(this.openIDrememberMeParameter) + renderHiddenInputs(request));
		sb.append("        <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n");
		sb.append("      </form>\n");
	}
	if (this.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 : this.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 : this.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();
}

登录页面url是/login,登录失败url是/login?error,登录表单url是/login(POST方式),登陆成功url是/login?logout,用户名参数名是username,密码参数名是password。