Spring Security를 이용해 로그인을 구현한 경우에 로그인한 사용자의 정보를 불러오는 방법에 대한 글이다. Show
@LoginUser 어노테이션 사용사용자 정보를 불어와야 할 메서드 인자로 @LoginUser 어노테이션을 이용해 SessionUser 객체를 전달한다. 위의 사진처럼 객체명을 user라고 했다면 메소드 내에서 user를 누른 다음 점(.)을 누르면 사용자 Entity 내의 있는 데이터를 불러올 수 있는 getter들의 리스트를 볼 수 있다. 끝이게 전부다. 정말 간단하다. 단지 필요한 메소드마다 객체를 불러와야 하지만 큰 단점은 아니라고 생각한다. 이번장에는 Spring Security에 대해 정리해보고자 한다. Spring Security를 어느정도 알고있는 상태에서 사용하면 편하지만 필자처럼 무작정 모르고 도입했다가 멘탈이 나갈(?) 수 있으 니 이번장에서 자세히 알아보자.
Security를 적용하기 위해 해당 의존성을 추가하자. Security Config 추가Line 40 : 사용자의 요청중 /resources/로 시작하는 요청은 제외한다. Spring
security에서 리소스별 접근권한을 정해줄때는 위에서부터 아래대로 순차적으로 적용된다. Line 49 : csrf 속성을 disable 시킨다. security가 적용된 애플리케이션에서 POST 방식으로 요청시 Line 52 : 해당url로 접근하면 로그인페이지로 이동하게된다. loginPage 설정을 하지않으면 Security에서 제공해주는 default 로그인페이지가 나오게 된다 Line 53 : 사용자가 로그인화면에서 아이디/비밀번호를 입력후 전송버튼 클릭시 전송되는 url이다. Line 54 / 55 : 로그인폼에 아이디와 비밀번호의 파라미터(name속성)명을 적어준다. Line 60 / 62 : /logout으로 요청이 오면 로그아웃을 시켜버리고 / 경로로 리다이렉트 해주며 Line 64 : 로그인
요청이 들어올 시 동작되는 Provider를 등록한다. 루트경로 매핑 및 로그인 컨트롤러, 페이지 생성좌측사진 : 사용자가 / 경로로 요청시 /login요청으로 리다이렉트 해준다. 구현클래스 생성AuthenticationProvider 구현체 생성로그인 요청시 AuthenticationProvider로 요청이 전달되며 authenticate() 메서드가 호출되며 인증받기전의 사용자의 정보가 authentication 객체에 담긴다. AuthenticationSuccessHandler 구현체 생성로그인이 정상적으로 동작하게되면 인증받은 사용자의 정보가 Authentication객체에 담기게 된다. AuthenticationFailureHandler 구현체 생성로그인이 정상적으로 동작되지않을때 어떠한 이유로 동작이 되지않았는지에 대한 예외가 AuthenticationException객체에 담긴다. UserDetails 구현체 생성사용자의 정보를 담고있는 VO 클래스이며 UserDetails를 구현한다. UserDetailsService 구현체 생성사용자의 정보를 DB에서 조회하는 단 하나의 메소드 loadUserByUsername()를 오버라이딩한다. 해당 메서드의 리턴타입은 UserDetails 타입이다. 사용자 정보조회사용자의 아이디를 인자로 받아서 DB에 사용자 정보를 조회한다. 사용자 인증처리사용자의 아이디로 DB에서 정보를 조회한다. 그리고 입력받은 비밀번호와 디비에 저장된 비밀번호(BCrypt 방식으로
해싱된)가맞지않으면 BadCredentialsException을 발생시킨다. 입력받은 비밀번호는 어떻게 비교 할까?똑같은 데이터를 암호화해도 BCrypt로 해싱을 하게되면 해싱과정에 salt값이 들어가기 때문에 암호화를
할때마다 로그인 성공 및 실패처리로그인에 성공하게되면 /study/list로 리다이렉트를 하고 실패하게되면 어떤 익셉션이 발생되었는지 콘솔에 찍어보자. 테스트할 사용자 계정 생성아이디 : test, 비밀번호 : 1234(해싱값), 권한 : USER를 부여한 테스트 계정을 생성하였다. 이 아이디로 테스트해보자. 테스트아이디 test, 비밀번호 1234를 입력후 로그인을 요청한 뒤 사용자 존재여부 및 비밀번호 체크후 정상적으로 로그인이 되어 CustomSuccessHandler에 의해 /study/list로 이동하였다. 이제 두가지 실패케이스를 한번 만들어보자. 아이디를 잘못입력하기비밀번호를 잘못입력하기아이디가 없으면 UsernameNotFoundException, 비밀번호가 맞지않으면 BadCredentialsException을 발생되야하는게 맞는데 뭔가 동작이 정상적으로 되지않는 것 같다. 에러메세지를 출력해주는 DaoAuthenticationProvider의 136 Line, 323 Line에 가보자 한번 가보자. Exception이 DaoAuthenticationProvider의 상위클래스인 AbstractUserDetailsAuthenticationProvider에서 발생되는걸 확인했다. Exception을 throw 했는데 CustomFailureHandler가 아닌 저기로 throw 되는걸까....설정파일을 확인해보니 필자가 다음과 같은 설정을 했었다. 해당설정 확인위 사진의 설정코드는 지우도록 하자. 아이디, 비밀번호 재 테스트정상적으로 테스트가 완료되었다. 하지만 이런 방법은 추천해주고 싶지않다. 만일 시큐리티로 자동로그인을 구현할때 default로 설정된 userDetailsService를 조회해서 사용자 정보를 조회하는 코드가 있는데 해당설정(auth.userDetailsService)을 제거하면 NPE가 발생된다. 그것보다는 위 사진 AbstractUserDetailsAuthenticationProvider의 아이디 또는 패스워드가 틀렸을 경우 DaoAuthenticationProvider나 AbstractUserDetailsAuthenticationProvider에서 예외메세지를 던지는데 MessageSourceAccessor객체의 getMessage() 메서드를 호출하여 해당 예외코드에 맞는 예외메세지를 가져오게끔 되있다. 만일 예외코드가 존재하지않으면 default message가 출력된다. 우리는 이 예외코드에 매핑되는 예외메세지를 설정하자 시큐리티 메세지 커스텀하기아이디 또는 패스워드가 틀릴경우 MeesageSourceAccesor객체에 'AbstractUserDetailsAuthenticationProvider.badCredentials' 라는 code로 매핑된 message값을 가져온다. 만일 등록된게 없다면 'Bad crecredentials' 라는 default Message를 던져준다. 이렇게 설정해두면 해당 code에 대한 예외메세지를 개발자가 직접 커스텀 할 수 있다. MessageSource 설정하는법은 아래링크를 통해 확인할 수 있다. kim-jong-hyun.tistory.com/26 14. Spring - MessageSource로 메세지 및 다국어 관리하기 이번장에는 Spring에서 제공해주는 MessageSource에 대해 알아보자. 웹개발을 하면서 화면단에 alert함수를 이용해 클라이언트에게 특정메세지를 보여줘야 할때가 많다. 이때 java에서 메세지값을 하드 kim-jong-hyun.tistory.com 아이디, 비밀번호 2차 테스트정상적으로 테스트가 완료되었다. |