정리노트

[스프링] 시큐리티

망고고래 2024. 1. 22. 17:51

ch08. 스프링 시큐리티

8.1 개요

8.2 접근 권한과 사용자 권한 설정

8.3 시큐리티 태그

8.4 로그인과 로그아웃 처리

 

8.1 개요

8.1.1 스프링 시큐리티

스프링 기반 애플리케션의 보안(인증과 권한)을 담당하는 프레임워크

 

환경 설정

(1)pom.xml 파일에 의존 라이브러리 등록

        <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-web</artifactId>
             <version>5.6.3</version>
        </dependency>
        <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-config</artifactId>
             <version>5.6.3</version>
        </dependency>

spring-security-web.jar: 필터 및 웹 보안 인프라 관련 코드 포함

spring-security-config.jar: 보안 네임 스페이스 구문 분석 코드 포함

 

(2)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>

 

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

 

 

 

(security-context.xml에 작성)

8.1.2 스프링 시큐리티 태그

접근 권한을 위한 태그/사용자 권한을 위한 태그

접근 권한: 허가된 사용자만 특정 페이지에 접근, 로그인 페이지 호출, 로그아웃 처리

사용자 권한 태그: 인증을 처리하기 위해 사용자 정보를 가져옴

태그 설명
<http> 시큐리티의 시작과 끝을 나타내는 데 사용
<intercept-url> 시큐리티가 감시해야 할 URL과 그 URL에 접근 가능한 권한을 정의
<form-login> 로그인 관련 설정
<logout> 로그아운 관련 설정
<authentication-manager> 사용자 권한 서비스의 시작과 끝 표시
<authentication-provider> 사용자 정보 인증 요청
<user-service> 사용자 정보를 가져오는 데 사용
<user> 사용자 정보를 나타내는 데 사용

 

 

 

8.2 접근 권한과 사용자 권한 설정

8.2.1 접근 권한을 설정하는 시큐리티 태그

(1)<http> 태그

최상위 태그

<http> 태그의 속성 설명
auto-config 일반적인 웹 애플리케이션에 필요한 기본 보안 서비스를 자동으로 설정
use-expressions <intercept-url> 태그의 access 속성에서 스프링 표현 언어(SpEL) 사용 가능

 

예시

<http auto-config='true' use-expressions="true">
...
</http>

 

 

(2)<intercept-url> 태그

접근 권한에 대한 URL 패턴 설정

<intercept-utl> 태그 속성 설명
pattern ant 경로 패턴으로 접근 경로 설정
access pattern 속성에 설정된 경로 패턴에 접근할 수 있도록 사용자 권한 설정
requires-channel 정의된 패턴 URL로 접근하면 설정된 옵션 URL로 리다이렉션(옵션: http, https, any)

 

 

ant 경로 패턴

  • ?: 문자 한 개와 매칭
  • *: 0개 이상의 문자와 매칭
  • **: 0개 이상의 디렉터리와 매칭

 

예시

   <http auto-config="true" use-expressions="true">
       <intercept-url pattern="/admin/**"  access="hasAuthority('ROLE_ADMIN')" />
        <intercept-url pattern="/manager/**"  access="hasRole('ROLE_MANAGER')" />
        <intercept-url pattern="/member/**"  access="isAuthenticated()" />
        <intercept-url pattern="/**"  access="permitAll" /> 
    </http>

 

 

스프링 표현 언어

표현 설명
hasRole([role]) 현 권한자가 지정된 [role]을 가지면 true 반환
[role]에서 'ROLE_' 접두어 생략 가능
hasAnyRole([role1, role2]) 현 권한자가 지정된 role 중에 하나를 가지면 true
[role]에서 'ROLE_' 접두어 생략 가능
hasAuthority([authority]) 현 권한자가 지정된 authority를 가지면 true 반환
[role]에서 'ROLE_' 접두어 생략 가능
hasAnyAuthority([authority1, authority2]) 현 권한자가 지정된 authority 중에 하나를 가지면 true
[role]에서 'ROLE_' 접두어 생략 가능
principal 현 사용자를 나타내는 주요 객체에 직접 접근할 수 있도록 허락
authentication SecurityContext에서 얻은 현 인증 객체에 직접 접근할 수 있도록 허락
permitAll 현 권한자에 상관없이 항상 true
denyAll 현 권한자에 상관없이 항상 false
isAnonymous() 현 권한자가 익명의 사용자이면 true 반환
isRememberMe() 현 권한자가 기억된 사용자이면 true
isAuthenticated() 사용자가 익명이 아니면 true 반환
isFullyAuthenticated() 익명의 사용자이거나 기억된 사용자가 아니면 true 반환

 

스프링 표현 언어 방식이 아닐 경우

권한 설명
ROLE_ADMIN 관리자
ROLE_USER 일반 사용자
ROLE_ANONYMOUS 모든 사용자
ROLE_RESTRICTED 제한된 사용자
IS_AUTHENTICATED_FULLY 인증된 사용자
IS_AUTHENTICATED_ANONYMOUSLY 익명 사용자
IS_AUTHENTICATED_REMEMBERED REMEMBERED 사용자

 

 

8.2.2 사용자 권한을 설정하는 시큐리티 태그

사용자 권한 서비스 태그

허가된 사용자의 아이디와 비밀번호 등 사용자 정보를 직접 설정하는 데 사용

사용자 권한 태그 종류 설명
<authentication-manager> 사용자 권한 인증을 위한 최상위 태그
<authentication-provider> 사용자 정보를 인증 요청 처리할 경우 사용
<user-service> 사용자 정보(사용자 ID, 사용자 암호, 권한 등)를 가져올 때 사용
<user> name, password, authorities 속성으로 사용자 정보를 나타낼 때 사용

 

사용자 권한 정보 설정 예시(아래는 모두 security-context.xml)

(1)<user> 태그

<beans:beans...>
<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="admin" password="{noop}1234" authorities="ROLE_ADMIN, ROLE_USER"/>
            <user name="manager" password="{noop}1235" authorities="ROLE_MANAGER"/>
            <user name="guest" password="{noop}1236" authorities="ROLE_USER"/>
        </user-service>
    </authentication-provider>
</authentication-manager>
</beans:beans>

 

(2)메시지 리소스 파일(*.properties)

<!-- properties 파일에 사용자 이름, 비밀번호, 권한 정보 등 작성 후 <user-servic> 태그 안에 설정 -->
<authentication-manager>
    <authentication-provider>
    <user-service properties="WEB-INF/user/users.properties"/>
    </authentication-provider>
</authentication-manager>

*properties 작성 예

admin=admin123, ROLE_ADMIN, ROLE_USER
user1=111, ROLE_USER
user2-222, ROLE_USER

 

(3)데이터베이스

<authentication-manager>
    <authentication-provider>
    <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>
</authentication-manager>

 

 

 

8.3 시큐리티 태그

JSP 뷰 페이지에서 보안 정보에 접근하고 보안 제약 조건을 적용하는 태그 라이브러리 지원

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

 

 

8.3.1 권한 태그: <sec:authorize>

<sec:authorize> 태그의 속성 설명
access 접근 권한 설정을 위한 정규 표현식
url 접근 권한이 설정된 사용자만 접근하도록 경로를 설정
var 접근 권한이 설정된 사용자를 변수로 재정의하여 설정

 

 

예시

package com.springmvc.chap08;

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

@Controller
public class Example02Controller {
	
	@GetMapping("/exam02")
	public String requestMethod(Model model) {
		return "webpage08_02";
	}
	
	@GetMapping("/manager/tag")
	public String requestMethod02(Model model) {
		return "webpage08_02";
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Security</title>
</head>
<body>
	<h2>스프링 시큐리티 태그</h2>
    <!-- 로그인했을 때 출력 -->
	<sec:authorize access="hasRole('ROLE_MANAGER')" var="isAdmin">
		<p><h3>매니저 권한 화면입니다.</h3>
	</sec:authorize>
	<c:choose>
    <!-- 로그인했을 때 출력 -->
		<c:when test="${isAdmin}">
			<p>ROLE_MANAGER 권한 로그인 중입니다.
			<p><a href="<c:url value='/exam02' /> ">[웹 요청 URL /exam02로 이동하기]</a>
		</c:when>
        <!-- 로그인 안 했을 때 출력 -->
		<c:otherwise>
			<p>로그인 중이 아닙니다.
			<p><a href="<c:url value='/manager/tag' /> ">[웹 요청 URL /manager/tag로 이동하기]</a>
		</c:otherwise>
	</c:choose>
</body>
</html>

 

8.3.2 인증 태그: <sec:authentication>

시큐리티 설정 파일에 저장된 현재 authentication 객체 접근 허용

JSP 뷰 페이지에서 property 속성을 사용해서 현재 authentication 객체에 직접 접근 가능

<security:authentication> 태그의 속성 설명
property 접근 권한이 설정된 현재 authentication 객체 이름
scope 접근 권한이 설정된 영역
var 접근 권한이 설정된 사용자를 변수로 재정의하여 설정

 

package com.springmvc.chap08;

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

@Controller
public class Example03Controller {

	@GetMapping("/exam03")
	public String requestMethod(Model model) {
		return "webpage08_03";
	}
	
	@GetMapping("/admin/tag")
	public String requestMethod2(Model model) {
		return "webpage08_03";
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Security</title>
</head>
<body>
	<h2>스프링 시큐리티 태그 예</h2>
	<sec:authorize access="hasRole('ROLE_ADMIN')" var="isAdmin">
		<p><h3>관리자 권한 화면입니다.</h3>
	</sec:authorize>
	<c:choose>
		<c:when test="${isAdmin}">
			<p>로그인 중입니다.
			<p>비밀번호: <sec:authentication property="principal.password"/>
			<sec:authentication property="authorities" var="roles" scope="page"/>
			<p>권한: 
				<ul>
					<c:forEach var="role" items="${roles}">
						<li>${role}
					</c:forEach>
				</ul>
			<p>이름: <sec:authentication property="principal.username"/>
			<p><a href="<c:url value='/exam03' /> ">[웹 요청 URL /exam03으로 이동하기]</a>
		</c:when>
		<c:otherwise>
			<p>로그인 중이 아닙니다.
			<p><a href="<c:url value='/admin/tag' /> ">[웹 요청 URL /admin/tag로 이동하기]</a>
		</c:otherwise>
	</c:choose>
</body>
</html>

 

 

 

 

8.4 로그인과 로그아웃 처리