1. 접근제한 설정
security-context.xml에 아래와 같이 접근 제한을 설정한다.
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:form-login/>
</security:http>
<security:authentication-manager>
</security:authentication-manager>
특정한 URI에 접근할 때 인터셉터를 이용해서 접근을 제한하는 설정은 <security:intercept-url>을 이용한다. <security:intercept-url>은 pattern이라는 속성과 access라는 속성을 지정해야만 한다. pattern 속성은 말 그대로 URI의 패턴을 의미하고, access의 경우는 권한을 체크한다. 위의 경우 '/sample/member'라는 URI는 'ROLE_MEMBER'라는 권한이 있는 사용자만이 접근할 수 있다.
access의 속성값으로 사용되는 문자열은 1) 표현식과 2) 권한명을 의미하는 문자열을 이용할 수 있다. <security:http>는 기본 설정이 표현식을 이용하는 것이다. 만일 단순한 문자열만을 이용하고 싶은 경우에는 use-expressions="false"를 지정한다. 아래 화면은 표현식을 사용하지 않는 경우에 권한을 지정하는 방식이다(표현식을 사용하는 방식이 권장되므로 예제에서는 사용하지 않는다).
<security:http auto-config="false" use-expressions="false">
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:form-login/>
</security:http>
설정을 변경하고 변경하고 WAS를 실행한 후 '/sample/member'를 접근해 보면 '/sample/all'과는 달리 '/sample/member'는 로그인 페이지('/login')로 강제로 이동하는 것을 볼 수 있다.
'login'에 해당하는 컨트롤러나 웹페이지를 제작한 적은 없다. 이것은 스프링 시큐리티가 기본으로 제공하는 페이지인데, 현실적으로는 별도의 로그인 펭지ㅣ르 ㄹ제작해야만 하므로 테스트하는 과정에서만 사용할 만하다.
2. 단순 로그인 처리
로그인 화면이 보여지기는 하지만 로그인을 할 수 없는 상황이므로, '/sample/member'에 접근할 수 있는 방법은 아무것도 없는 상황이다. 추가적인 설정을 통해서 지정된 아이디와 패스워드로 로그인이 가능하도록 설정을 추가해 보자.'스프링 시큐리티에서 명심해야 하는 사항 중 하나는 username이나 User라는 용어의 의미가 일반적인 시스템에서의 의미와 차이가 있다는 점이다. 일반 시스템에서 userid는 스프링 시큐리티엣는 username에 해당한다. 일반적으로 사용자의 이름을 username이라고 처리하는 것과 혼동하면 안된다.
User라는 용어 역시 혼란의 여지가 있다. 스프링 시큐리티의 User는 인증 정보와 권한을 가진 객체이므로 일반적인 경우에 사용하는 사용자 정보와는다른 의미이다. 예제에서는 이를 구분하기 위해서 시스템상의 회원 정보는 MemberDto라는 클래스를 이용할 것이다. 단순히 로그인이 처리되는 것을 확인하기 위해서 메모리상에 문자열을 지정하고 이를 기준으로 동작하도록 설정해 보자.
인증과 권한에 대한 실제 처리는 UserDetailsService라는 것을 이용해서 처리하는데, xml에서는 다음과 같이 지정할 수 있다.
security-context.xml
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="member" authorities="ROLE_MEMBER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
추가된 설정의 핵심은 'member'라는 계정 정보를 가진 사용자가 로그인을 할 수 있도록 하는 것이다. 위의 설정을 추가한 후에 WAS를 통해서 '/sample/member'로 접근해서 로그인하면 예상과 달리 에러가 발생한다.
실행 결과에서 에러는 'PasswordEncoder'라는 존재가 없기 때문에 발생한다.
스프링 시큐리티 5버전부터 반드시 PasswordEncoder라는 존재를 이용하도록 변경되었다. 스프링 시큐리티 4버전까지는 PasswordEncoder의 지정이 없어도 동작했지만, 5부턴 반드시 필요하다
임시 방편으로 스프링 시큐리티 5버전에서는 포맷팅 처리를 지정해서 패스워드 인코딩 방식을 지정할 수 있다.
https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-format
만일 패스워드의 인코딩 처리없이 사용하고 싶다면 패스워드 앞에 '{noop}' 문자열을 추가한다.
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
3. 로그아웃 확인
스프링 시큐리티를 학습하다 보면 매번 로그아웃하고 새롭게 로그인을 해야 하는 상황이 자주 발생한다. 이에 대해서 가장 확실한 방법은 브라우저에서 유지하고 있는 세션과 관련된 정보를 삭제하는 것이다. 개발자 도구에서 Application 탭을 확인해 보면 'Cookie' 항목에 'JSESSIONID'와 같이 세션을 유지하는데 사용되는 세션 쿠기의 존재를 확인할수 있다.
로그아웃은 JSESSIONID 쿠키를 강제로 삭제해서 처리한다.
'spring' 카테고리의 다른 글
[스프링 시큐리티] 로그인과 로그아웃 처리(3) (0) | 2020.10.23 |
---|---|
[스프링 시큐리티] 로그인과 로그아웃 처리(2) (0) | 2020.10.23 |
Interface HttpServletRequest (0) | 2020.10.23 |
Class DispatcherServlet (0) | 2020.10.23 |
Spring Web Security 설정 (0) | 2020.10.22 |