일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Jenkins
- local
- Java
- pkgutil
- change file content
- install maven
- 줄복사
- remove
- key bindings
- javaascript
- ADB
- duplicate lines
- ^M바꾸기
- spring boot
- maven
- driverspy
- object
- gradle
- jdbc
- install
- ubuntu
- svn backup
- JavaScript
- mariadb
- not to accept jdbcUrl
- JAR
- spring
- docker
- Change port
- 전송포맷
- Today
- Total
Simplify
Spring Boot - (7-1) Login 성공 시점에 처리 로직 구현 본문
Spring Boot - (7-1) Login 성공 시점에 처리 로직 구현
Simplify - Jonghun 2018. 10. 8. 17:32GitHub 소스 위치 : https://github.com/Simplify-study/SpringBootSample.git
앞서 Spring Security 를 구현한 내용에 따르면, 화면에서 넘어온 username 과 password를 이용해서 DB를 조회하고, 조회된 결과 정상적인 사용자이고, 그 사용자의 Authority 정보가 있으면 그것들을 조회해서 별도의 SecurityMember 라는 객체(User, 혹은 UserDetail 을 상속받는)로 만들고 session 을 유지해준 채 로그인 처리를 마무리합니다.
이러한 일련의 과정들은 아주 기본적인 사항만이 적용된 경우이고, 더 상세한 부분에 대해서는 앞으로 하나하나 추가해 나갈 전망입니다. 여기서는 로그인이 성공한 이후에 다음의 과정을 한 뒤에 로그인 완료 처리를 하는 것으로 개발 해 보겠습니다.
- 로그인한 사용자의 IP 정보 저장하기
- 로그인 이전에 요청했던 URL이 있으면, 로그인이 성공한 뒤, 그 URL로 Redirect 해 주기
사실 이러한 처리를 위해서는 두 가지 경우에 처리로직을 추가할 수 있습니다. authenticationSuccessHandler와 authenticationFailureHandler가 그것입니다. 둘 다 구현체만 만들어주고 앞서 만든 Configure 함수에 추가만 해주면 그럴듯하게 동작합니다.
AuthenticationSuccessHandler 구현하기
파일을 하나 생성하고, 적당히 이름을 넣습니다. 저는 SuccessHandler라고 이름 지었고, AuthenticationSuccessHandler 를 상속받게 만들려다가 SavedRequestAwareAuthenticationSuccessHandler 를 상속받는 것으로 아래와 같이 만들었습니다.
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | package com.simplify.sample.handlers; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import com.simplify.sample.security.domain.SecurityMember; public class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { public CustomLoginSuccessHandler(String defaultTargetUrl) { setDefaultTargetUrl(defaultTargetUrl); } @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { ((SecurityMember)authentication.getPrincipal()).setIp(getClientIp(request)); HttpSession session = request.getSession(); if (session != null) { String redirectUrl = (String) session.getAttribute("prevPage"); if (redirectUrl != null) { session.removeAttribute("prevPage"); getRedirectStrategy().sendRedirect(request, response, redirectUrl); } else { super.onAuthenticationSuccess(request, response, authentication); } } else { super.onAuthenticationSuccess(request, response, authentication); } } public static String getClientIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } } | cs |
위에 보이는 것 처럼 onAuthenticationSuccess 함수에서 로그인이 성공했을때에 대한 처리를 해 주었습니다. 저는 로그인 성공 시점에 로그인한 사용자의 IP 정보를 request 를 통해서 알아내, SecureMember 에 넣어주었고, 기존 요청했던 URL이 있다면 그 쪽으로 redirection 해 주는 식으로 개발하였습니다.
그리고 WebSecurityConfigurerAdapter 에 아래 부분을 추가합니다.
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 42 43 44 45 46 47 48 49 50 | package com.simplify.sample.security.adapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import com.simplify.sample.handlers.CustomLoginSuccessHandler; import com.simplify.sample.security.service.CustomUserDetailsService; @EnableWebSecurity public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Autowired CustomUserDetailsService customUserDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationSuccessHandler successHandler() { return new CustomLoginSuccessHandler("/"); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers("/openapi/**", "/resources/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().formLogin().successHandler(successHandler()); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); } } | cs |
AuthenticationFailureHandler 구현하기
다음으로 AuthenticationFailureHandler로 구현해 보기로 합니다. 구현채만 만들 뿐, 안에 내용은 만들지 않았습니다. 향후 Logback 설정을 완료하고 나면 그때 로그나 한줄 남기는 것으로 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.simplify.sample.handlers; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; public class CustomLoginFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { // TODO Auto-generated method stub } } | cs |
에제 실행을 하고 로그를 확인해 보면, 아래와 같이 로그인이 성공한 시점에 IP 정보를 정상적으로 받아옴을 알 수 있습니다.
'Web & Server > Spring & Spring Boot' 카테고리의 다른 글
Spring Boot - (9) Property, Authentication Principal (0) | 2018.10.10 |
---|---|
Spring Boot - (8) Logback 상세화하기 (2) | 2018.10.08 |
Spring Boot - (7) Security 적용 및 로그인 설정 (0) | 2018.10.06 |
Spring Boot - (6) 민감 정보 숨기기(DB id, password, etc.) (4) | 2018.10.02 |
Spring Boot - (5) JSP 연동하기 (+Model and View) (1) | 2018.10.01 |