티스토리 뷰

728x90
반응형

 

 

 

 

spring security를 이용한 사용자인증 및 로그인 기능을 구현하는 방법에 대해서 작성해봅니다.

spring security에 대한 내용은 아래 포스팅 2개를 참고하세요.

 

[springboot] spring security로 DB 사용자권한별 페이지접속제한하기

https://domdom.tistory.com/656

 

[springboot] spring security로 DB 사용자권한별 페이지접속제한하기

먼저, 로그인 페이지를 만들어줍니다. 컨트롤러에 로그인 페이지를 생성해주세요. // Controller @RequestMapping("/login") public String login() throws Exception { return "login"; } 연결된 로그인 html파일에는 다음과

domdom.tistory.com

 

[java] spring security 로그아웃기능 만들기 (+자동로그아웃)

https://domdom.tistory.com/660

 

[java] spring security 로그아웃기능 만들기 (+자동로그아웃)

예전에 spring security로 로그인, 사용자권한별 페이지접속에 대해서 글을 적은적이 있는데요. 이번에는 로그아웃 기능을 만들고, 아래와 같이 3가지 기능을 추가해보려고 합니다. 1. 로그아웃버튼

domdom.tistory.com

 

 

 

 

토큰을 이용해 사용자인증 및 로그아웃하는 방법에 대한 내용입니다.

먼저 springSecurity에 아래 내용을 추가해줍니다.

addFIlterBefore는 사용자접속 시 우선적으로 처리해줄 메소드를 추가해주는 것입니다.

userDetailsFromToken 메소드에서 토큰을 체크할 것입니다.

토큰없이 들어온 사용자이거나, 토큰값 에러 시 이동할 /error 페이지는 모두 접속가능하도록 설정해줍니다.

 

http
	.addFilterBefore(new UserDatilsFromToken(), UsernamePasswordAuthenticationFilter.class)

	.authorizeRequests()
		.antMatchers("/error").permitAll() // 로그인안해도 사용 가능

 

 

 

 

토큰 확인하는 페이지("/")와 로그아웃페이지("/logout")는 POST로 데이터를 전송받기 때문에 

csrf 인증을 무시하도록 설정해주었구요.

토큰을 이용하여 사용자인증을 진행할 것이기에 .formLogin().disable()로 로그인 기능을 없애줍니다.

이를 disable 해주지않으면 사이트접속 시 로그인페이지가 뜨게됩니다.

 

	.and()
    	.csrf().ignoringAntMatchers("/", "/logout") // 접속 시 SSO 토큰 받을 때는 CSRF 보호 비활성화

	.and()
    	.formLogin().disable() // 로그인기능없음 (SSO 토큰이용)

 

 

 

로그아웃 관련 설정을 추가합니다.

그리고  토큰 인증으로 사용자가 인증된 후 로그아웃을 하면 토큰확인페이지("/")로 이동되도록 설정해주었습니다.

 

        .logout()
            .logoutUrl("/logout")  // 로그아웃 처리 URL
            .logoutSuccessUrl("/")  // 로그아웃 성공 후 리다이렉트할 URL
            .invalidateHttpSession(true)  // 세션 무효화
            .deleteCookies("JSESSIONID"); // 쿠키 제거

 

 

 

그리고나서, 토큰 인증 메소드를 구현해줍니다.

deoFilterInternal 메소드는 사용자가 어느 페이지에 접속을 하든 무조건 실행됩니다.

따라서 토큰인증을 진행하지 않아도 되는 페이지들은 예외처리를 해주고,

토큰을 통해 사용자를 인증하는 코드를 작성해주시면 됩니다.

 

 

@Service
public class UserDatilsFromToken extends OncePerRequestFilter{
@Override
	protected void doFilterInternal(
			HttpServletRequest request,
			HttpServletResponse response,
			FilterChain filterChain
			) throws IOException, ServletException {
		
		// 특정 페이지에서는 토큰확인절차 없이 바로 페이지로 이동
		if (request.getRequestURI().startsWith("/error") // 에러페이지로 이동했따던지 
				|| request.getRequestURI().equals("/logout")) // 로그아웃페이지로 이동했다던지
		{ 
			filterChain.doFilter(request, response);
			return;
		}
		// 이미 인증된 사용자이면 토큰확인절차 패스
		if (SecurityContextHolder.getContext().getAuthentication() != null
				&& SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
			filterChain.doFilter(request, response);
		}
		
		// 접속된 URL 출력
		System.out.println("접속URL : "+ request.getRequestURI());
		
		// 전송받은 토큰
		String token = request.getParameter("token");
		
		// 토큰없이 들어왔다면 에러페이지로 이동시킴
		if (token == null) {
			response.sendRedirect("/error");
			return;
		}else{
			// 토큰정보 인증
			UserDetails userdetails = loadUserByToken(token);
			if (userdetails != null) {
				// 인증 성공 시, SecurityCOntextHolder에 인증 정보 설정
				UsernamePasswordAuthenticationToken authentication = 
						new UsernamePasswordAuthenticationToken(userdetails, null, userdetails.getAuthorities());
				SecurityContextHolder.getContext().setAuthentication(authentication);
			}
		}
		
	}
	
	// 토큰을 이용한 사용자 정보 인증
	public UserDetails loadUserByToken(String token) {

		// 토큰을 이용해 사용자 정보를 불러온다
		....
		return new org.springframework.security.core.userdetails.User(
				.... );
	}

}

 

 

 

이제 서버를 실행시키고 테스트를 해봅니다.

저는 터미널로 curl 명령어를 통해 인증 테스트를 진행했습니다.

 

curl 명령어로 수행된 HTTP 요청들은 서로 독립적이라서, 

한 curl 요청에서 수행된 인증 상태(예: 로그인)는 다른 curl 요청에 자동으로 전달되거나 유지되지 않습니다.
첫 번째 curl -i -X POST http://localhost/ -d token=test 요청에서 인증이 완료되었다 하더라도,

이후의 curl -i -X GET http://localhost/ 요청은 이전 요청과는 완전히 별개로 처리됩니다.

 

따라서, 두 번째 요청은 인증 상태를 "알지 못합니다".

curl로 상태를 유지하려면 다음과 같은 방법을 사용할 수 있습니다:

# 쿠키 저장
curl -c cookies.txt -X POST http://localhost/ -d token=test

# 저장된 쿠키 사용
curl -b cookies.txt -i -X GET http://localhost/

 

 

사용자가 토큰없이 접속했다면 token은 null값으로 들어오게 되구요.

 

 

 

 

정상적으로 토큰값을 입력받았다면 토큰값 처리 후 사용자 인증이 진행됩니다.

아래와 같이 200 OK가 뜨면서 쿠키값이 나왔다면 성공!

 

 

 

 

 

실행 경로 폴더에 cookies.txt가 자동으로 저장됩니다.

 

 

 

 

사용자인증된 쿠키를 사용해 로그아웃까지 진행해봅니다.

로그아웃도 마찬가지로 POST로 전달해야합니다.

로그아웃 시 302 Found가 뜨는 이유는,

로그아웃이 된 후  "/"페이지로 이동되었기 떄문입니다. (Location: http://localhost/ )

 

 

 

 

spring security로 SSO토큰을 통해 사용자인증 및 로그아웃 하는 방법에 대해 알아보았습니다.

끝!

 

 

 

 

728x90
반응형
댓글