Shiro 기반 사용자 인증 및 권한 관리 개요
Apache Shiro는 자동화된 인증과 권한 부여를 지원하는 강력한 보안 프레임워크입니다. 본 문서에서는 Groovy 기반의 웹 애플리케이션에서 Shiro를 적용하여 사용자 인증을 수행하는 방법을 실습 중심으로 설명합니다.
기본 개념: 인증과 권한
보안 시스템의 핵심 요소는 인증(사용자 신원 확인)과 권한(접근 제어)입니다. 인증은 사용자가 자신이 주장한 정체성과 일치하는지 검증하는 과정이며, 일반적으로 사용자 이름과 비밀번호 조합을 통해 이루어집니다. 권한은 인증된 사용자가 특정 리소스에 접근할 수 있는지를 결정하는 메커니즘입니다.
Shiro는 이러한 보안 작업을 간단한 API로 제공하며, 다양한 데이터 소스와 호환됩니다. 예를 들어, JDBC, LDAP, Kerberos, Microsoft Active Directory 등 다양한 인증 백엔드를 지원합니다.
Shiro 설치 및 환경 구성
Shiro는 라이브러리 형태로 제공되며, 직접 다운로드하거나 Maven, Ivy 등을 통해 의존성 관리를 할 수 있습니다. 아래는 Apache Ivy를 이용한 설정 예시입니다.
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
<info organisation="com.example" module="shiro-demo" />
<dependencies>
<dependency org="org.apache.shiro" name="shiro-core" rev="1.0.0-incubating" />
<dependency org="org.apache.shiro" name="shiro-web" rev="1.0.0-incubating" />
<dependency org="commons-logging" name="commons-logging" rev="1.1.1" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.5.8" />
</dependencies>
</ivy-module>
기본 인증 테스트 코드
다음은 기본적인 인증 테스트를 위한 자바 코드입니다. 먼저 `SecurityManager`를 초기화하고, 현재 사용자를 가져온 후 인증 여부를 확인합니다.
package com.example.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AuthTest {
private static final Logger logger = LoggerFactory.getLogger(AuthTest.class);
public static void main(String[] args) {
Factory<org.apache.shiro.mgt.SecurityManager> factory =
new IniSecurityManagerFactory("security.ini");
SecurityUtils.setSecurityManager(factory.getInstance());
Subject currentUser = SecurityUtils.getSubject();
logger.info("현재 사용자 인증 상태: " + currentUser.isAuthenticated());
UsernamePasswordToken token = new UsernamePasswordToken("admin", "secret");
try {
currentUser.login(token);
logger.info("인증 성공: " + currentUser.isAuthenticated());
} catch (Exception e) {
logger.error("인증 실패: " + e.getMessage());
}
}
}
INI 파일 기반 사용자 정의
인증 정보는 `security.ini` 파일에 정의할 수 있습니다. 예를 들어 다음과 같이 사용자 계정을 설정할 수 있습니다.
[users]
admin = secret
user = password
LDAP 기반 인증 설정
Active Directory 또는 기타 LDAP 서버를 통한 인증도 가능합니다. 다음은 로컬에 실행 중인 Apache Directory 서버를 대상으로 한 설정 예시입니다.
[main]
ldapRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
ldapRealm.systemUsername = uid=admin,ou=system
ldapRealm.systemPassword = secret
ldapRealm.searchBase = o=sevenSeas,ou=people
ldapRealm.url = ldap://localhost:10389
Grails 애플리케이션 통합
Grails 프레임워크는 내장된 웹 서버를 제공하며, Shiro 필터를 쉽게 통합할 수 있습니다. 플러그인 방식으로 `web.xml` 생성 과정에 필터를 삽입할 수 있습니다.
class ShiroWebXmlPlugin {
def doWithWebDescriptor = { xml ->
def filter = xml.'filter'
def lastFilter = filter[filter.size() - 1]
lastFilter + {
'filter' {
'filter-name'('ShiroFilter')
'filter-class'('org.apache.shiro.web.servlet.IniShiroFilter')
'init-param' {
'param-name'('config')
'param-value'('\n#config')
}
}
}
def mapping = xml.'filter-mapping'
def lastMapping = mapping[mapping.size() - 1]
lastMapping + {
'filter-mapping' {
'filter-name'('ShiroFilter')
'url-pattern'('/*')
}
}
}
}
플러그인 생성 후, 애플리케이션을 실행하면 자동으로 필터가 등록되고, 모든 요청이 Shiro의 보안 체크를 거칩니다.
문제 해결 팁
- UnavailableSecurityManagerException:
SecurityUtils.setSecurityManager()호출이 누락되었는지 확인하세요. - CommunicationException: LDAP 서버 주소나 포트가 올바른지 점검하세요. Apache Directory Studio를 활용해 연결 상태를 진단할 수 있습니다.
- 의존성 누락 시, commons-beanutils 등 필요한 라이브러리 추가 필요.