Hayden's Archive
[Spring] Spring Web Security 설정 본문
참고 :
책 - 코드로 배우는 스프링 웹 프로젝트 ( book.naver.com/bookdb/book_detail.nhn?bid=13993776 )
카페 - 구멍가게코딩단( cafe.naver.com/gugucoding )
Spring Security 설명
- 거의 대부분 웹 기반 프로젝트에서 사용자의 권한이나 등급에 기반을 두는 로그인 체크를 이용
- 스프링 시큐리티를 이용하면 다음과 같은 작업들을 간편히 처리할 수 있음
- 로그인 처리와 CSRF 토큰 처리
- 암호화 처리
- 자동 로그인
- JSP에서의 로그인 처리
- 스프링 시큐리티의 기본 동작 방식 : 서블릿의 여러 종류의 필터(Filter)와 인터셉터(Interceptor)를 이용해서 처리
- 필터는 서블릿에서 말하는 단순한 필터를 의미
- 인터셉터는 스프링에서 필터와 유사한 역할
- 유사점 : 특정한 서블릿이나 컨트롤러의 접근에 관여한다
- 차이점
- 필터는 스프링과 무관하게 서블릿 자원. 서블릿 컨텍스트에 속하긴 하지만 스프링과 무관.
- 인터셉터는 스프링의 빈으로 관리되면서 스프링의 컨텍스트 내에 속함. 스프링의 내부에서 컨트롤러를 호출할 때 관여하므로 스프링의 컨텍스트 내에 있는 모든 자원을 활용할 수 있음.
- 스프링 시큐리티 이용 -> 인터셉터와 필터를 이용하면서 별도의 컨텍스트를 생성하여 처리
- 스프링 시큐리티는 현재 동작하는 스프링 컨텍스트 내에서 동작 -> 이미 컨텍스트에 포함된 여러 빈들을 같이 이용해서 다양한 방식의 인증 처리가 가능하도록 설계 가능
Spring Security 최소한의 설정
이제 본격적으로 실습을 해보자.
스프링 프로젝트를 생성하고 pom.xml에 다음과 같이 추가한다.
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.3.5.RELEASE</version>
</dependency>
<!-- JSP에서 스프링 시큐리티와 관련된 태그 라이브러리 활용 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.3.5.RELEASE</version>
</dependency>
spring 폴더 아래 Spring Bean Configuration File 메뉴를 통해 security-context.xml 을 생성한다.
그리고 security-context.xml 의 네임스페이스에서 security 항목을 체크하고 저장한다.
그리고 나서 소스로 와보면 다음과 같이 되어 있다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-5.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
이제 스프링 시큐리티를 스프링 MVC에서 사용하기 위해 필터를 이용해서 스프링 동작에 관여하도록 설정한다.
web.xml에 다음 코드를 추가한다.
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
프로젝트를 실행하면 다음과 같은 에러가 뜬다.
org.springframework.beans.factory.NoSuchBeanDefinitionException:
springSecurityFilterChain이라는 빈이 제대로 설정되지 않았다.
web.xml에 <context-param>을 다음 코드로 수정하여 위에서 작성한 security-context.xml을 로딩하도록 설정한다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml
</param-value>
</context-param>
security-context.xml에 다음과 같이 최소한의 설정을 추가한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-5.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<security:http>
<security:form-login/>
</security:http>
<security:authentication-manager>
</security:authentication-manager>
</beans>
프로젝트를 실행하여 오류가 나지 않는 것을 확인한다.
접근 제한 설정
security-context.xml에 다음을 추가하여 접근 제한을 설정한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-5.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<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>
</beans>
특정한 URI에 접근할 때 인터셉터를 이용해서 접근을 제한하는 설정은 <security:intercept-url>을 이용한다. 여기서 pattern 속성은 URI의 패턴을 의미하고, access는 권한을 의미힌다.
'/sample/member'라는 URI는 'ROLE_MEMBER'라는 권한이 있는 사용자만 접근 가능!
<security:intercept-url>의 access의 속성값으로 사용되는 문자열은 1) 표현식과 2) 권한명을 의미하는 문자열을 이용할 수 있음
hasRole("ROLE_MEMBER")
표현식 없이 단순한 문자열만을 이용하고 싶은 경우에는 use-expression="false"로 지정. (보통은 표현식을 사용한다)
<security:http auto-config="true" use-expressions="false">
<security:intercept-url pattern="/sample/member" access="ROLE_MEMBER"/>
<security:form-login/>
</security:http>
설정을 반영하고 프로젝트를 실행하여 '/simple/all'로 접근하면 접근이 되는 반면 '/simple/member'는 로그인 페이지로 강제 이동한다.
(/login 에 해당하는 컨트롤러나 웹페이지를 만들지 않아도 그럼. 스프링 시큐리티가 기본으로 제공하는 테스트용 페이지.)