티스토리 뷰
application을 구현하다보면 jsp에서 분기처리를 해서 권한에 따라서 다른걸 보여줘야 하는 상황이 발생한다. 이럴때 기존의 JSTL 을 사용하여 if 문으로 분기처리를 할수도 있지만 객체를 받아와서 그걸 풀고 그에 따라 분기처리를 하는 부분은 어찌보면 복잡하게 느껴질수도 있다. 이런 상황일때 spring security 를 사용하여 권한관리를 하고 있다면 간단하게 구현을 할 수 있다.
AuthenticationProvider의 구현체에서 role을 정의하고 UsernamePasswordAuthenticationToken에 정의된 role을 집어 넣는 과정이 모두 끝났다면 spring security tag library를 통해 어디서든 role을 사용할 준비는 끝이 났다.
Spring Security Tag Library 사용법
pom.xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${springsecurity.version}</version>
</dependency>
제일 먼저 할일은 spring security tag library를 사용할 수 있도록 dependency를 추가해주자.
context-security.xml
<http auto-config="true" use-expressions="true">
다음으로 할일은 applicationContext ( eg. context-security.xml )에서 spring security 정의를 할때 다음 구문을 추가시켜줘야한다. use-expression="true"
jsp
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
그리고 jsp에서 spring security tag library를 사용하기 위한 준비를 한다. sec라는 이름으로 사용할것이다.
이제 sec tag를 사용할 것이다. 사용하기 전에 하나의 가정을 하고 시작하자. 현재 이 application의 ROLE은 ROLE_ADMIN, ROLE_MANAGER, ROLE_EMPLOYEE 이렇게 3개만 있다고 가정하자. 이럴때 역할별로 어떻게 구분을 해서 쓸지에 대한 예를 보도록 하겠다.
<sec:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_MANAGER')">
<div class="grid-sample" style="height: 600px;">
<div id="grid_data" style="height: 600px;"></div>
</div>
</sec:authorize>
위처럼 <sec:authorize> 라는 spring security tag를 사용해서 이런걸 할 수 있다. 위 코드를 해석하면 "hasAnyRole에 포함된 권한이면 무엇이든지 접근할 수 있다." 라는 뜻이다. 즉 ROLE_ADMIN, ROLE_MANAGER는 <sec:authorize>로 감싸진 grid를 볼 수 있다는 것이다. 당연히 ROLE_EMPLOYEE에게는 보이지 않는다. 위에서 얘기했던것처럼 JSTL로 이것을 구현하려면 꽤 많은 과정이 필요한데 spring security tag를 사용하면 이렇게 쉽게 권한에 따라 분기처리를 할 수 있다. 이 hasAnyRole만 알아도 충분히 유용하게 사용할 수 있지만 하는김에 다른 옵션들은 뭐가 더 있는지 보자.
Common built-in expressions
Expression |
Description |
hasRole([role]) |
현재 주체에 지정된 역할이 있는지 여부를 반환 합니다. 제공된 역할이 'ROLE_'로 시작하지 않으면 기본적으로 추가됩니다. DefaultWebSecurityExpressionHandler의 defaultRolePrefix을 수정하여 사용자 정의를 할 수 있습니다. |
hasAnyRole([role1,role2]) |
현재 주체에 제공된 역할 (쉼표로 구분 된 문자열 목록으로 제공됨)이 있는지 여부를 반환 합니다. 제공된 역할이 'ROLE_'로 시작하지 않으면 기본적으로 추가됩니다. DefaultWebSecurityExpressionHandler의 defaultRolePrefix을 수정하여 사용자 정의를 할 수 있습니다. |
hasAuthority([authority]) |
현재 주체에 지정된 권한이 있는지 여부를 반환 합니다. |
hasAnyAuthority([authority1,authority2]) |
현재 주체에 제공된 역할 (쉼표로 구분 된 문자열 목록으로 제공됨)이 있는지 여부를 반환 합니다. |
principal |
현재 사용자를 나타내는 주체 개체에 직접 액세스 할 수 있습니다. |
authentication |
SecurityContext Authentication에서 얻은 현재 개체에 직접 액세스 할 수 있습니다. |
permitAll |
항상 허용 |
denyAll |
항상 불허 |
isAnonymous() |
현재 주체가 익명 사용자인 경우 true 반환 |
isRememberMe() |
현재 주체가 remember-me 사용자 인 경우 true 반환 |
isAuthenticated() |
사용자가 익명이 아닌 경우 true 반환 |
isFullyAuthenticated() |
사용자가 익명 또는 remember-me 사용자가 아닌 경우 true 반환 |
hasPermission(Object target, Object permission) |
사용자가 주어진 권한에 대해 제공된 대상에 액세스 할 수 있는지 여부를 반환합니다. 예를 들면 hasPermission(domainObject, 'read') |
hasPermission(Object targetId, String targetType, Object permission) |
사용자가 주어진 권한에 대해 제공된 대상에 액세스 할 수 있는지 여부를 반환합니다. 예를 들면 hasPermission(1, 'com.example.domain.Message', 'read') |
출처 : https://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/el-access.html#el-access-web
번역기 돌려서 너무 어색한 부분만 수정을 했는데 여전히 어색하다..
이것저것 옵션들이 많은데 이중 많이 쓰이는것은 hasAnyRole()과 isAuthenticated() isAnonymous() 정도이다. 위의 Common Built-in Expression은 jsp 뿐만 아니라 applicationContext를 구성할때도 사용할 수 있다. spring security 공통으로 사용할 수 있는 표현법인 것이다. spring security 를 자주 사용할 것이라면 위의 표현식은 잘 이해를 해야 한다.
끝!
'Framework > Security' 카테고리의 다른 글
KeyCloak WildFly Management 실행 및 기본사용법 (0) | 2020.11.04 |
---|---|
KeyCloak 기본포트(8080) 다른 포트로 변경하기 (0) | 2020.11.04 |
MSA 인증서비스를 쉽게 해주는 KeyCloak 설치하기 (0) | 2020.11.03 |
Spring Security에서 Custom Filter 생성하고 등록하기 (0) | 2020.07.08 |
Spring Security 에서 SSO로 로그인시 HttpSessionAttributeListener를 활용해 중복로그인 방지하기 (0) | 2020.05.06 |