본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Spring Framework

[Spring] Spring Security(1) - 기본 사용법

by 김코더 김주역 2021. 1. 19.
반응형

만약 관리자 페이지처럼 특정 계정으로만 접근 해야하는 페이지를 만들어야 한다면 어떻게 할까?

이번 포스팅에서 다룰 Spring Security를 사용한다면 이 궁금증을 해결할 수 있다. 이제 사용법을 알아보자.

 

1. Dependency 추가

Spring Security를 사용하기 위해 pom.xml에 dependency 4개를 다음과 같이 추가해준다.

버전은 가급적 Spring 버전과 동일하게 하는게 좋다. 본인은 여기서 버전 문제로 상당한 시간을 날렸다.

<dependencies>

  ...
  
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>3.1.1.RELEASE</version>
  </dependency>
  
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>3.1.1.RELEASE</version>
  </dependency>
  
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>3.1.1.RELEASE</version>
  </dependency>
  
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>3.1.1.RELEASE</version>
  </dependency>
</dependencies>

 

 

2. Security 설정 파일 작성

appServlet 폴더 우클릭 -> New -> Other... 에서 Spring Bean Configuration File을 선택한다.

 

설정 파일 이름은 security-context.xml로 정했다.

 

beans, context, security를 선택하여 스키마를 자동으로 추가시킨다.

 

 

<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:context="http://www.springframework.org/schema/context"
	xmlns:s="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<s:http auto-config="true" use-expressions="true">
		<s:intercept-url pattern="/login.html*" access="isAnonymous()"/>
		<s:intercept-url pattern="/vip.html*" access="hasRole('ROLE_USER')"/>
		<s:intercept-url pattern="/admin.html*" access="hasRole('ROLE_ADMIN')"/>
		<s:access-denied-handler error-page="/"/>
	</s:http>
		
	<s:authentication-manager>
		<s:authentication-provider>
			<s:user-service>
				<s:user name="codelove" password="1365" authorities="ROLE_USER"/>
				<s:user name="kimcoder" password="1366" authorities="ROLE_USER, ROLE_ADMIN"/>
			</s:user-service>
		</s:authentication-provider>
	</s:authentication-manager>
	
</beans>

사용자가 특정 url 패턴으로 요청을 하면, 여기서 먼저 인증 절차를 거친다.

먼저, security 스키마를 네임스페이스 s로 쓸 수 있게 xmins:s 로 스키마를 추가했다.

s:intercept-url의 pattern이 방금 언급한 특정 url 패턴이고, access에서는 권한을 체크한다.

권한이름(authorities)은 s:user에서 name, password와 같이 생성할 수 있으며, spring security에서 제공하는 로그인 페이지에서 name, password를 맞게 입력했을 경우 해당 권한을 획득할 수 있게 된다. 그리고 권한은 한 번에 2개 이상 가질 수도 있다.

권한을 가진 사용자는 해당 pattern에 맞는 url에 접근할 수 있게 되는 것이다.

마지막으로, s:access-denied-handler는 접근 오류(403) 페이지를 대체할 페이지를 설정할 수 있다. error-page를 "/"로 설정하여 403 page를 home page로 redirect시킨다.

 

※ access 설명

s:http의 use-expressions를 true로 설정해야 다음과 같이 메소드 형태로 권한을 체크할 수 있다.

  • isAnonymous() : 익명일 때만 접근 허용(로그인 상태에서는 접근을 허용하지 않음)
  • hasRole('role') : 해당 권한이 있다면 접근 허용
  • hasAnyRole('role1', 'role2') : 하나의 권한이라도 가진다면 접근 허용
  • isAuthenticated() : 이미 로그인 인증을 받은 User일 경우 접근 허용, 익명 사용자는 로그인 페이지로 이동
  • isRememberMe() : 자동 로그인 대상 User일 경우 접근 허용
  • isFullyAuthenticated() : 자동 로그인 없이 로그인 인증을 받은 User일 경우 접근 허용
  • permitAll : 모두 접근 허용
  • denyAll : 모두 접근 미허용

 

 

<servlet-context.xml>

특별히 추가된 코드는 없다.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.example.demo" />
</beans:beans>

 

 

3. web.xml에 Security 설정 파일 적용

<web.xml>

context-param의 param-value에 아까 작성한 security 설정 파일 경로를 추가했다.

그리고 security를 적용할 수 있게 모든 요청에 <filter>를 적용했다.

그리고 모든 요청은 .html로 받도록 servlet-mapping도 수정해주었다.

이 외에 특별히 추가된 부분은 없다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring/root-context.xml
			/WEB-INF/spring/appServlet/security-context.xml
		</param-value>
	</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>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/spring/appServlet/servlet-context.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>*.html</url-pattern>
	</servlet-mapping>
	
	<filter>
	<filter-name>encodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
	<param-name>encoding</param-name>
	<param-value>UTF-8</param-value>
	</init-param>
	</filter>
	
	<filter-mapping>
	<filter-name>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

 

 

servlet-mapping에서 모든 요청은 .html로 받도록 했기 때문에 Controller도 수정이 필요하다.

 

<HomeController.java>

(RequestMapping 어노테이션으로 지정한 경로 뒤에 html을 추가)

vip.jsp, admin.jsp 에서는 사용자가 각각 vip, admin 페이지로 들어왔음을 명시만 했다.

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	@RequestMapping("/vip.html")
	public String vip(Model model) {
		return "vip";
	}
	
	@RequestMapping("/admin.html")
	public String admin(Model model) {
		return "admin";
	}
}

 

 

4. 실행

demo/vip.html 또는 demo/admin.html로 요청

spring security에서 제공하는 로그인 페이지이다.

접근 권한을 인증 받아야 진행할 수 있게 필터가 정상적으로 적용된 것이며, security-context.xml에서 설정한 해당 name, password를 입력해야 통과된다.

 

로그인 성공(vip.jsp)

 

로그인 성공(admin.jsp)

 

로그인 실패

 

 

다음 포스팅에서는 spring security에서 제공하는 로그인 페이지가 아닌,

직접 만든 로그인 페이지를 적용해보는 시간을 가질 것이다.

kimcoder.tistory.com/245

 

[Spring] Spring Security(2) - 로그인 페이지 구현

Spring Security(1) 포스팅에서는 spring security에서 제공하는 로그인 페이지로 인증 절차를 거칠 수 있었다. kimcoder.tistory.com/244 [Spring] Spring Security(1) - 기본 사용법 만약 관리자 페이지처럼 특..

kimcoder.tistory.com

 

 

 

 

반응형

'Spring Series > Spring Framework' 카테고리의 다른 글

[Spring] Mybatis  (0) 2021.01.26
[Spring] Spring Security(2) - 로그인 페이지 구현  (0) 2021.01.20
[Spring] JDBC 트랜잭션  (0) 2021.01.14
[Spring] JdbcTemplate  (0) 2021.01.11
[Spring] 게시판 설계 준비과정  (0) 2021.01.07

댓글