Apache Shiro 는 JSP 또는 GSP 페이지에서 보안 컨텍스트에 기반하여 UI 요소를 제어할 수 있는 태그 라이브러리를 제공합니다. 이를 통해 로그인 상태, 역할, 권한 등에 따라 버튼이나 메뉴를 동적으로 표시하거나 숨길 수 있습니다.
태그 라이브러리 설정
JSP 페이지 상단에서 Shiro 태그 라이브러리를 선언하여 사용할 수 있습니다. 표준 URI 를 사용하며, 접두사는 프로젝트 규약에 따라 변경 가능합니다.
<%@ taglib prefix="sec" uri="http://shiro.apache.org/tags" %>
해당 태그 라이브러리는 shiro-web 모듈 내의 META-INF/shiro.tld 파일에 정의되어 있습니다.
인증 상태 기반 태그
사용자의 인증 상태에 따라 다른 콘텐츠를 노출할 수 있습니다.
guest 태그
로그인하지 않은 방문객에게만 표시되는 영역입니다.
<sec:guest>
<span>비회원 사용자입니다.</span>
<a href="${pageContext.request.contextPath}/account/signin">로그인 페이지로 이동</a>
</sec:guest>
user 태그
로그인되었거나 '기억하기' 기능을 통해 식별된 사용자에게 표시됩니다.
<sec:user>
<p>환영합니다, <sec:principal/> 님</p>
<a href="${pageContext.request.contextPath}/account/signout">로그아웃</a>
</sec:user>
authenticated 태그
현재 세션에서 명시적으로 로그인 인증 (Subject.login) 을 성공한 사용자에게만 표시됩니다. '기억하기'로 자동 로그인된 경우는 포함되지 않습니다.
<sec:authenticated>
<div>인증된 사용자: <sec:principal/></div>
</sec:authenticated>
notAuthenticated 태그
명시적인 로그인 인증을 수행하지 않은 상태입니다. '기억하기'로 로그인된 상태도 이 조건에 해당합니다.
<sec:notAuthenticated>
<span>인증 절차가 필요합니다.</span>
</sec:notAuthenticated>
사용자 정보 출력 (principal)
현재 보안 주체 (Subject) 의 정보를 화면에 출력합니다. 기본적으로 Subject.getPrincipal() 를 호출합니다.
특정 타입의 Principal 을 추출할 수 있습니다.
<sec:principal type="java.lang.String"/>
이는 Subject.getPrincipals().oneByType(String.class) 와 동일하게 동작합니다. 또한 Principal 객체의 특정 프로퍼티를 직접 접근할 수도 있습니다.
<sec:principal property="accountName"/>
위 코드는 ((User)Subject.getPrincipal()).getAccountName() 를 호출한 것과一样的한 결과를 반환합니다.
역할 (Role) 검사 태그
사용자가 특정 역할을 보유했는지 여부를 확인합니다.
hasRole
지정된 단일 역할을 가지고 있을 경우 본문을 렌더링합니다.
<sec:hasRole name="manager">
<p>관리자 권한이 있는 사용자입니다.</p>
</sec:hasRole>
hasAnyRoles
콤마로 구분된 역할 목록 중 하나라도 보유하고 있으면 표시됩니다.
<sec:hasAnyRoles name="manager,member">
<p>관리자 또는 일반 회원입니다.</p>
</sec:hasAnyRoles>
lacksRole
지정된 역할을 가지고 있지 않을 경우 표시됩니다.
<sec:lacksRole name="guest">
<p>게스트 역할이 할당되지 않았습니다.</p>
</sec:lacksRole>
권한 (Permission) 검사 태그
사용자가 특정 권한을 보유했는지 확인하여 기능을 제어합니다.
hasPermission
지정된 권한 문자열을 보유할 경우 내용을 표시합니다.
<sec:hasPermission name="board:write">
<button>글 작성하기</button>
</sec:hasPermission>
lacksPermission
지정된 권한이 없을 경우 내용을 표시합니다.
<sec:lacksPermission name="system:delete">
<span>시스템 삭제 권한이 없습니다.</span>
</sec:lacksPermission>
커스텀 태그 확장
기본 태그 외에 추가적인 논리가 필요한 경우 태그 파일 (Tag File) 을 통해 확장할 수 있습니다.
<%@ taglib prefix="ext" tagdir="/WEB-INF/tags" %>
예를 들어, 모든 역할을 동시에 만족하는지 확인하거나 복잡한 권한 조합을 검사하는 태그를 정의하여 사용할 수 있습니다.
<ext:hasAllRoles name="manager,editor">
<p>관리자이자 편집자입니다.</p>
</ext:hasAllRoles>
<ext:hasAllPermissions name="board:write,board:delete">
<p>글 작성 및 삭제 권한을 모두 보유합니다.</p>
</ext:hasAllPermissions>
<ext:hasAnyPermissions name="board:write,comment:write">
<p>글 또는 댓글 작성 권한이 있습니다.</p>
</ext:hasAnyPermissions>
이러한 확장을 통해 NOT, AND, OR 등 복잡한 보안 논리를 뷰 계층에서 깔끔하게 처리할 수 있습니다.