티스토리 뷰
spring security를 이용한 사용자인증 및 로그인 기능을 구현하는 방법에 대해서 작성해봅니다.
spring security에 대한 내용은 아래 포스팅 2개를 참고하세요.
[springboot] spring security로 DB 사용자권한별 페이지접속제한하기
https://domdom.tistory.com/656
[java] spring security 로그아웃기능 만들기 (+자동로그아웃)
https://domdom.tistory.com/660
토큰을 이용해 사용자인증 및 로그아웃하는 방법에 대한 내용입니다.
먼저 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토큰을 통해 사용자인증 및 로그아웃 하는 방법에 대해 알아보았습니다.
끝!
'프로그래밍 > Java' 카테고리의 다른 글
[intellij] java spring project 실행시 JCTree qualid 관련 오류 해결 (3) | 2024.04.11 |
---|---|
[오류해결] java.lang.NullPointerException: Cannot invoke "service..." because "this.service" is null 에러 (37) | 2024.01.10 |
[spring boot] Java EE에서 Jakarta EE로의 전환 (48) | 2023.12.06 |
[spring boot] WAS를 JBoss(wildfly) 사용한 개발환경 만들기-2 (43) | 2023.12.05 |
[spring boot] WAS를 JBoss(wildfly) 사용한 개발환경 만들기-1 (21) | 2023.12.02 |