Spring Secuirty 3 기본 로그인 페이지
포스트
취소

Spring Secuirty 3 기본 로그인 페이지

우리는 지난시간에 권한이 없는 유저가 권한이 필요한 api 를 호출할때 어떤 식으로 로그인 페이지로 인도하는지 보았다 다만 여기서 의문점은 우리는 로그인 페이지를 만들지 않았는데 시큐리티는 알아서 로그인 핸들러와 , 로그인 페이지를 인도하는 모습을 보여주었다 어떻게 이런일이 가능할까? 물론 시큐리티 내부적으로 이러한 기본적인 로그인 페이지를 가지고 있다가 필요할때 렌더링을 진행해서 사용자에게 보여주게 됩니다

스크린샷 2023-08-06 105416

우리가 최초로 로그인을 할려고 하면 이런 화면이 보이게 됩니다 이런 화면은 DefaultLoginPageGeneratingFilter 로 생성이 되게 되는데

DefaultLoginPageGeneratingFilter

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
	}

DefaultLoginPageGeneratingFilter 는 사용자가 커스텀 로그인 페이지를 만들지 않는다면 자동으로 기본적인 로그인 페이지를 제공하게끔 만들어진 Filter 입니다 이때 로그인 페이지를 만드는 부분은 String loginPageHtml = generateLoginPageHtml(request, loginError, logoutSuccess); 이 부분에 해당이 됩니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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");

		...

		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");
}
		...

		sb.append("</body></html>");
		return sb.toString();
	}

if (this.formLoginEnabled) 이 if문을 통해서 우리가 현재 하고 있는 from 로그인을 사용하고 있기에 이 부분이 true 가 되어서 렌러링이 되게 됩니다 다른것을도 렌더링할 수 있지만 지금은 사용하지 않기에 전부 false 가 되어서 렌더링을 하지 않습니다

formLoginEnabled 로 인해서 지금처럼 로그인 form 을 만들게 되는것이죠 그리고 renderHiddenInputs 이라는 메서드를 통해서 필요한 몇가지 태그를 더 넣게 되는데 이떄 제일 대표적으로 들어가는 input 이 csrf 필터입니다 이 csrf Filter 는 다음에 설명할 일이 있을예정이고

1
2
<input name="_csrf" type="hidden" value="7ade26eb-23dc-4d32-adaa-3165e3685629">

이런 결과를 거쳐서 우리가 지금 보고 있는 로그인 페이지를 보게 되는것입니다.