Spring Security관련해서 질문 있습니다.

2017-07-26 23:33

개발환경: Spring Boot사용

우선 서비스 요구사항을 알려 드리겠습니다.

  1. 로그인 성공 시, 해당 사용자가 "2차 로그인"을 사용하는지 여부를 판단한다.

  2. 만약 사용한다면, 2차 로그인 화면이 나온다. 2차 로그인 화면이 나왔을 때는, 사용자가 임의적으로 url에 어떠한 url을 넣어도 2차 로그인 화면만 나오게 해야한다.

머리 속으로 구현 할 프로세스를 한번 잡아보았습니다.

  1. AuthenticationProvider 인터페이스를 구현한 클래스에서 로그인 성공 시 HttpSession에 2차 로그인 사용 여부 정보를 담습니다. ex) session.setAttribute("2차로그인", "yes"); session.setAttribute("2차로그인", "no"):

  2. WebSecurityConfigurerAdapter를 상속받은 클래스에서

boolean isSecureLogin = session.getAttribute("2차로그인");

if(isSecureLogin == true) {

 http.authorizeRequests()
        .antMatchers("/strongLogin**").permitAll() // 2차 로그인 view & 로직 처리를 담당 할 url
        .antMatchers("/**").denyAll()
        .and()
        .exceptionHandling().accessDeniedPage("/strongLogin"); // 다른 url접속 시 2차 로그인 view 출력

}

제가 지금 자바 백엔드 신입 개발자인데, 해당 부분을 구현하기위해 5일째, 스프링 시큐리티 개념부터 공부하고 해당 부분을 구현하고있는데 도저히 모르겠습니다.

도와주시면 정말 감사하겠습니다.

3개의 의견 from SLiPP

2017-07-27 12:25

2차 로그인 인증이 필요하다니 다소 생소한 요구사항이네요.

저도 이런 요구사항을 받아본 경험이 없는지라 제가 제안하는 방법이 100% 맞다고 보장할 수는 없지만 저는 다음과 같이 접근해 볼 것 같아요.

일단 2차 로그인이 필요하다는 것은 1차 로그인을 완료한 상태여야겠죠? 그럼 기본으로 ROLE_USER와 같은 권한은 가져야할 것 같네요. 1차 로그인은 spring security로 당연히 구현했을테고요.

2차 로그인은 spring security에 추가하지 않고 spring의 interceptor를 활용해 구현할 것 같아요. 현재 로그인한 사용자가 2차 로그인이 필요한 사용자인지 판단한 후에 2차 로그인이 필요하면 2차 로그인 페이지로 redirect 시켜버리는 방식으로 구현할 듯 합니다.

그럼 spring security 설정은 다음과 같겠죠.

http.authorizeRequests()
        .antMatchers("/strongLogin**").hasRole("USER");

즉, 로그인한 사용자만 접근할 수 있어야 하기 때문에 USER 권한을 가진 사용자로 한정해야 하겠죠. 그럼 /strongLogin에서 2차 로그인 페이지로 보낸 후에 2차 인증을 처리하는 Controller로 보내버리면 되겠죠.

2차 인증 Controller 구현이 핵심일 듯 한데요. 만약 2차 인증을 성공하면 기존의 spring security 로그인 정보를 삭제하고 2차 인증을 통한 새로운 로그인 정보(Authentication)을 넣어주면 됩니다.

spring security에서 인증을 성공했을 때 인증 정보는 다음 코드와 같이 SecurityContextHolder에 담겨 있는 Authentication으로 확인할 수 있어요.

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

이 부분의 Authentication을 2차 인증 정보로 바꿔주면 될 것 같아요. 이 부분은 위와 반대로 setAuthentication() 메소드 활용하면 됩니다.

Authentication authentication = "2차 인증 결과에 따른 authenticatio 생성";
SecurityContextHolder.getContext().setAuthentication(authentication);

위와 같이 처리하면 기존의 spring security의 기본 기능을 그대로 활용하면서 2차 인증을 구현할 수 있지 않을까 생각합니다.

저도 구현해 본 후에 답변 드리는 것은 아니기 때문에 너무 확신하지는 마시고요. 반드시 spring security 내에서만 해결하려고 하지 마셨으면 해요. spring security 내에서 해결하려면 customizing 해야될 부분이 너무 많을 것 같네요.

2017-07-28 12:26

답변 정말 감사드립니다.

아직 6개월차다보니 스프링 시큐리티에만 꼽혀서 그쪽만 바라봤던 것 같습니다. 앞으로는 넓게 볼 수 있는 시야를 키워야겠네요

구현 성공하게되면 그때 결과도 공유할게요. 감사합니다.

2017-07-28 17:01

저라면 아마도..

  1. Auth Provider로 1차 인증 시도(username + password)

  2. 인증 성공시 2차 인증 필요 여부 확인.

2-1. 2차 인증 필요 없을 경우, 인증 최종 성공으로 처리.

2-3. 2차 인증 필요한 경우, 인증 작업을 중단하고 3번으로 이동.

  1. 1차 인증이 성공했으므로 JWT로 토큰을 생성. Claim으로 username을 추가하고, 만료를 5분 정도로 잡음.

  2. 302 Status로 2차 인증 페이지로 이동하도록 함(방금 만든 JWT도 헤더에 담아서 함께..)

  3. 사용자가 2차 인증 페이지에서 2차 비밀번호 입력시, JWT와 함께 서버에 재전송.

  4. JWT Claim 안의 username과 전달된 2차 Password를 통해 2차 인증 진행.

박재성 교수님 말씀하신대로.. 이부분도 2차 인증 Controller가 문제겠지만, '2차 인증이 필요한 계정이 1차 인증에 성공한 경우'에 인증 정보를 따로 저장하지 않도록 하게 되겠네요.

이건 아마도 제가 '2차 인증이 필요한 계정은 2차 인증까지 통과해야 정상적인 인증 성공' 이라고 생각해서 그럴지도 모르겠습니다.

덧. JWT는.. 선택 사항이 될 수도 있을것 같습니다. :)

의견 추가하기

연관태그

← 목록으로