[Spring] 시큐리티

Whatever·2022년 2월 11일
0

Spring(스프링)

목록 보기
19/29

1. 스프링 시큐리티란?

  • 애플리케이션에서 보안 기능을 구현하는 데 사용되는 프레임워크(디자인패턴 + 라이브러리 집합)
  • 필터 기반으로 동작하므로 스프링 MVC와 분리되어 동작함

2. 주요 기능

  • 인증(Authentication) : 사용자의 정당성 확인(로그인)
  • 인가(Authorization) : 리소스나 처리에 대한 접근 제어(권한)

3. 제공 기능

  • 세션관리
  • 로그인 처리
  • 암호화 처리
  • 자동 로그인
  • CSRF(Cross-site request forgery) 토큰 처리
    : 웹 사이트 취약점 공격을 막아줌
    : 사용자가 자신도 모르게 공격자가 의도한 행위(수정, 삭제, 등록)을 특정 웹 사이트에 요청하게 하는 공격

4. 웹 화면 접근 정책

: 시큐리티 설정(security-context.xml)을 통해서 특정 URI에 대한 접근을 제한함

1) 회원게시판(board)

  • 목록(list) : 모두 접근 가능
  • 등록(register) : 로그인한 회원만 접근 가능

2) 공지사항 게시판(notice)

  • 목록(list) : 모두 접근 가능
  • 등록(register) : 로그인한 관리자만 접근 가능

5. JDBC를 이용한 인증/인가 처리

1) 지정된 형식으로 테이블을 생성해야 함
2) USERS(사용자 관리), AUTHORITIES(권한 관리)


다운로드 및 세팅 - 5.0.7 버전

1. 다운로드

web


config

core

taglibs

2. pom.xml에 추가

		<!-- 스프링 시큐리티 라이브러리 의존관계 정의 시작 -->
		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-web</artifactId>
		    <version>5.0.7.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-config</artifactId>
		    <version>5.0.7.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-core</artifactId>
		    <version>5.0.7.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-taglibs</artifactId>
		    <version>5.0.7.RELEASE</version>
		</dependency>
		<!-- 스프링 시큐리티 라이브러리 의존관계 정의 끝 -->

3. web.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>
    
	<!-- 서블릿 필터 클래스를 서블릿 컨테이너에 등록함 -->
	<!-- url-pattern : 어디에 적용할것이냐, /* : 모든 경로에 적용 -->
	<filter>
		<filter-name>springSecurityFiterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>springSecurityFiterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>    

4. servlet-context 설정

아래 소스 추가

	<!-- kr.or.ddit.security 패키지를 컴포넌트 스캔 대상으로 함 -->
	<context:component-scan base-package="kr.or.ddit.security" />

5. security-context.xml 생성, 설정

beans 설정

<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.xsd">	

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.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 로그인 실패! 
	접근 거부가 발생한 상황(member 계정으로 /notice/register를 요청 시)에 
	단순 메시지 처리 이상의 다양한 처리를 하고자 한다면 AccessDeniedHandler를 직접 구현해야 함
	CustomAccessDeniedHandler를 빈으로 등록함
	-->
	<bean id="customAccessDenied" 
		class="kr.or.ddit.security.CustomAccessDeniedHandler"></bean>
	
	<!-- 로그인 성공!
	인증(로그인) 성공 처리자 AuthenticationSuccessHandler
	-->
	<bean id="customLoginSuccess"
		class="kr.or.ddit.security.CustomLoginSuccessHandler"></bean>
	
	<!-- 사용자가 정의한 비밀번호 암호화 처리기를 빈으로 등록 -->
	<bean id="customPasswordEncoder"
		class="kr.or.ddit.security.CustomNoOpPasswordEncoder"></bean>
	
	<!-- 스프링 시큐리티의 UserDetailService를 구현해서 사용자의 상세 정보를 얻어오기 위함 -->
	<bean id="customUserDetailService" 
		class="kr.or.ddit.security.CustomUserDetailService"></bean>
	
	<security:http>
	<!-- URI 패턴으로 접근 제한을 설정함 
	pattern : url 요청 경로 
	access  : 접근 제한 정책
	-->
		<security:intercept-url pattern="/board/list" access="permitAll" />
		<security:intercept-url pattern="/board/register" 
			access="hasRole('ROLE_MEMBER')" />
		<security:intercept-url pattern="/notice/list" access="permitAll" />
		<security:intercept-url pattern="/notice/register" 
			access="hasRole('ROLE_ADMIN')" />
		
		<!-- 폼 기능 인증 기능 사용. 
		접근 제한에 걸리면 스프링 시큐리티가 기본적으로 제공하는 로그인 페이지로 이동함 -->
<!-- 		<security:form-login /> -->
<!-- 		<security:form-login  -->
<!-- 			authentication-success-handler-ref="customLoginSuccess" /> -->
		<!-- 사용자가 정의한 로그인 페이지의 URI를 지정함 -->
<!-- 		<security:form-login login-page="/login" /> -->
		<security:form-login login-page="/login" 
			authentication-success-handler-ref="customLoginSuccess" />
		
		<!-- 접근 거부 처리자(접근 거부가 발생한 상황을 처리)의 URI를 지정 -->
<!-- 		<security:access-denied-handler error-page="/accessError" /> -->
		<!-- 
		개발자가 등록한  CustomAccessDeniedHandler를 접근 거부 처리자로 지정함
		- 공지사항 등록 화면(/notice/register)은 회원(member)의 접근이 불가능한 페이지(관리자만 접근 가능)
		- 지정된 접근 거부 처리자(CustomAccessDeniedHandler)의 처리(Handle) 메서드를 자동 호출함
		- 지정된 접근 거부 처리자(CustomAccessDeniedHandler)에서 
		    접근 거부 처리 페이지(/accessError)로 리다이렉트(요청 흐름이 이동) 시킴
		-->
		<security:access-denied-handler ref="customAccessDenied" />
		
		<!-- 로그아웃. 세션을 무효화 함 -->
		<security:logout logout-url="/logout" invalidate-session="true" />
	</security:http>
	
	<security:authentication-manager>
	<!-- 
	지정된 아이디와 패스워드로 로그인이 가능하도록 설정함 
	authorities : ROLE_MEMBER, ROLE_ADMIN
	member 사용자 : /board/list, /board/register, /notice/list
	admin 사용자   : /board/list, /board/register, /notice/list, /notice/register
	
	스프링 시큐리티 5버전부터는 패스워드 암호화 처리기를 반드시 이용하도록 변경이 되었음
	암호화 처리기를 사용하지 않도록 "{noop}" 문자열을 비밀번호 앞에 사용.
	-->
<!-- 		<security:authentication-provider> -->
<!-- 			<security:user-service> -->
<!-- 				<security:user name="member" password="{noop}1234"  -->
<!-- 					authorities="ROLE_MEMBER"/> -->
<!-- 				<security:user name="admin" password="{noop}abcd"  -->
<!-- 					authorities="ROLE_MEMBER,ROLE_ADMIN"/> -->
<!-- 			</security:user-service> -->
<!-- 		</security:authentication-provider> -->
		<!-- 인증 매니저에 인증 제공자를 등록 -->
		<!-- 
		CustomUserDetailService 빈을 인증 제공자에 지정함 
		스프링 시큐리티의 UserDetailService를 구현해서 사용자의 상세 정보를 얻어오기 위함
		-->
		<security:authentication-provider user-service-ref="customUserDetailService">
			<!-- 데이터 소스 지정 -->
<!-- 			<security:jdbc-user-service data-source-ref="dataSource" /> -->
<!-- 			<security:jdbc-user-service  -->
<!-- 				data-source-ref="dataSource" -->
<!-- 				users-by-username-query="SELECT MEMBERID, PASSWORD, ENABLED FROM MEMBER WHERE MEMBERID=?" -->
<!-- 				authorities-by-username-query="SELECT B.MEMBERID, A.AUTH FROM MEMBER_AUTH A, MEMBER B WHERE A.MEMBERID = B.MEMBERID AND B.MEMBERID=?" -->
<!-- 			/> -->
			
			<!-- 사용자가 정의한 비밀번호 암호화 처리기 지정 -->
			<security:password-encoder ref="customPasswordEncoder" />
		</security:authentication-provider>
	</security:authentication-manager>
	
</beans>

0개의 댓글