원하는대로

관심분야에 대해 원하는 모든 것을 발행하는 곳

미정 자세히보기

공부 스걱스걱/웹

[Spring Security] 스프링 세큐리티 설정(spring boot 없이)

ohsoou 2021. 11. 10. 14:31

웹 프로젝트를 진행하던 중 관리자페이지를 만들어야 했다.

관리자 페이지는 해당 URL에 접근을 관리자 아니면 아예 할 수 없게 하고싶어 찾던 중 Spring Security라는 프레임워크을 알게되었다. 

개발 환경
Spring 5.2.17.RELEASE
Spring Security 5.5.2
STS 3.9.17.RELEASE
Spring MVC Poroject

 

Spring Security 문서를 보면서 설정했다.

https://docs.spring.io/spring-security/site/docs/current/reference/html5/

 

Spring Security Reference

In Spring Security 3.0, the codebase was sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. If you use Maven to build your project, these are the modules you should add to your pom.xml. Ev

docs.spring.io

1. pom.xml 설정

4.2.2. Maven Without Spring Boot 부분을 보면서 pom.xml에 dependency를 추가했다. 

spring-security-taglibs를 추가로 등록해줬는데 JSP에서 Security 관련 조건이나 정보를 확인하기 위해 사용된다.

	<!-- Spring Security -->
    <dependency>
    	<groupId>org.springframework.security</groupId>
        <artifactId>spring-security-bom</artifactId>
        <version>${spring-security-version}</version>
        <type>pom</type>
        <scope>import</scope>
	</dependency>
    <dependency>
    	<groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring-security-version}</version>
	</dependency>
    <dependency>
    	<groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring-security-version}</version>
	</dependency>
    <dependency>
    	<groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>${spring-security-version}</version>
	</dependency>

 

2. web.xml 설정

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/spring/*-context.xml</param-value>
</context-param>

나는 security-context.xml 이라는 이름으로 spring secuirty 설정 파일을 만들었기 때문에 위와같이 -context.xml 이 뒤에 붙은 파일을 모두 context-param으로 만들도록 설정한다.

<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>

Spring 문서에서 18.2.1. web.xml Configuration 부분에 나온 바와 같이 Request가 오면 Spring Security에서 처리할 수 있도록 위와같이 필터를 설정한다.

3. security-context.xml

해당 파일의 위치는 root-context.xml이 있는 곳에 만들었다.

먼저 namespace에서 아래와 같이 체크해준다. 

namespace 설정

Spring 문서 18.1. Introduction 부분에 나온 것을 참고해 설정한다.

<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.xsd
	http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
</beans>

 

그 다음 resources 들은 모두 통과할 수 있게 설정을 추가한다.

<security:http pattern="/resources/**" security="none"/>

아래는 Spring 문서에 나온대로 기본 설정을 마친 파일이다.

Spring 문서 18.2.2. A Minimal <http> Configuration 부분에 잘 나와있다.

<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.xsd
	http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

	<security:http pattern="/resources/**" security="none"/>
	<security:http>
		<security:intercept-url pattern="/**" access="hasRole('USER')" />
		<security:form-login />
		<security:logout />
	</security:http>
    
<security:authentication-manager>
	<security:authentication-provider>
		<security:user-service>
			<security:user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
			<security:user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
		</security:user-service>
	</security:authentication-provider>
</security:authentication-manager>

</beans>

아래는 나의 프로젝트에 맞게 모든 설정을 마친 최종본이다.

나는 커스텀 로그인 페이지와 DB user 객체 연결, 암호화를 추가했다.

<security:http pattern="/admin/**" auto-config="true" use-expressions="true">
	<security:csrf disabled="true"/>
	<security:intercept-url pattern="/admin/main" access="hasAnyRole('ROLE_MASTER', 'ROLE_ASSISTANTE')" />
	<security:intercept-url pattern="/admin/site" access="hasAnyRole('ROLE_MASTER', 'ROLE_ASSISTANTE')" />
	<security:intercept-url pattern="/admin/user" access="hasAnyRole('ROLE_MASTER')" />
    
    <!--custom 로그인 페이지 설정-->
	<security:form-login
		username-parameter="id"
		password-parameter="password"
		login-page="/admin/login"
		default-target-url="/admin/main"
		login-processing-url="/admin/perform_login" 
		authentication-failure-url="/admin/login?error=true"
		always-use-default-target="true"
	/>
    <!--로그아웃 url 설정-->
	<security:logout logout-url="/admin/logout" logout-success-url="/admin/login"/>
</security:http>
    

<security:authentication-manager>
	<!--user-service DB 연동-->
	<security:authentication-provider user-service-ref="adminLogin">
    <!--BCryptPasswordEncoder 설정-->
	<security:password-encoder ref="passwordEncoder"/>
	</security:authentication-provider>
</security:authentication-manager>

<!--위에서 ref로 사용할 bean 등록-->
<bean id="adminLogin" class="com.kgitbank.jeju.admin.service.AdminLoginService"/>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>