[Spring] Spring-Security 설정하기

yunSeok·2023년 10월 19일
0

Spring Security

목록 보기
1/2

스프링 시큐리티란?

Spring Security는 Java 애플리케이션, 특히 Spring Framework를 기반으로 구축된 애플리케이션을 위해 만들어진 사용자가 정의 가능한 인증 및 액세스 제어 프레임워크입니다.
말 그대로 Spring 설정에서 보안을 담당합니다.

기능

  • 사용자 인증 및 권한 부여: Spring Security는 사용자 인증 및 권한 부여 기능을 제공합니다. 이를 통해 애플리케이션에 액세스할 수 있는 사용자를 제어하고, 각 사용자에게 허용된 작업을 제어할 수 있습니다.

  • 데이터 암호화: Spring Security는 데이터 암호화 기능을 제공합니다. 이를 통해 애플리케이션의 데이터를 외부 공격으로부터 보호할 수 있습니다.

  • 접근 제어: Spring Security는 접근 제어 기능을 제공합니다. 이를 통해 애플리케이션의 특정 리소스에 대한 액세스를 제어할 수 있습니다.


설정

1. pom.xml에 dependency 추가하기

    <properties>
        <org.springframework-version>5.3.29</org.springframework-version>
		<org.aspectj-version>1.9.19</org.aspectj-version>
		<org.slf4j-version>2.0.7</org.slf4j-version>
		<spring.security-version>5.8.1</spring.security-version> 
    </properties>

    <!-- security -->
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
	<dependency>
	    <groupId>org.springframework.security</groupId>
		<artifactId>spring-security-web</artifactId>
		<version>${spring.security-version}</version>
	</dependency>

	<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-core</artifactId>
		<version>${spring.security-version}</version>
	</dependency>

	<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-config</artifactId>
		<version>${spring.security-version}</version>
	</dependency>

	<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-taglibs</artifactId>
		<version>${spring.security-version}</version>
	</dependency>
  • propertiessecurity-version 설정되어 있는지 확인해주세요!
  • security-taglibs는 JSP에서 Security 기능을 태그 형태로 간단하게 제공하기 때문에 추가해주었습니다.

2. web.xml 설정

   <!-- 모든 서블릿 필터에 적용되는 Root Spring Container -->
   <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>multipartFilter</filter-name>
        <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>multipartFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-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>
       <init-param> 
           <param-name>forceEncoding</param-name> 
           <param-value>true</param-value> 
       </init-param> 
   </filter> 
   <filter-mapping> 
       <filter-name>encodingFilter</filter-name> 
       <url-pattern>/*</url-pattern> 
   </filter-mapping>

   <!-- Security 기능 제공 -->
	<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>

📌 주의 사항!!

  • multipartFilter는 파일 업로드 요청을 처리하기 때문에 springSecurityFilterChain 보다 먼저 실행되어야 해서 위에 작성해줍니다.
  • 그 다음 인코딩을 진행해야 하고,
  • springSecurityFilterChain을 작성해줍니다.

✅ springSecurityFilterChain filter

  • DelegatingFilterProxy 클래스를 사용하여 구현
    • Spring Security 필터를 사용하는 시작점으로 설정되며, 서블릿 컨테이너 영역(WAS)의 필터와 Spring Container에서 Spring Bean으로 등록된 필터를 연결하는 역할을 합니다.
  • 기능
    • 인증(Authentication) : 사용자의 인증을 처리합니다.
    • 인가(Authorization) : 사용자의 권한을 확인합니다.
    • 보안 : 사용자의 요청을 보호합니다

3. security-context.xml 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	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/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
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
   

	<http auto-config="true" use-expressions="true">
		<intercept-url pattern="/user/join" access="permitAll" />
		<intercept-url pattern="/**" access="permitAll" /> 
		<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
		
		<form-login 
		         login-processing-url="/user/login"
		         username-parameter="id"
		         password-parameter="pw"
		         default-target-url="/post"
		         authentication-success-handler-ref="customLoginSuccessHandler"
		         authentication-failure-handler-ref="customLoginFailureHandler"
		/>
		
		<access-denied-handler ref="customAccessDeniedHandler"/>
		<logout logout-url="/logout" logout-success-url="/post" invalidate-session="true" delete-cookies="JSESSIONID"/>
		<remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
        
	</http>
   
	<authentication-manager>
		<authentication-provider user-service-ref="customUserDetailsService">
	  		<password-encoder ref="bcryptPasswordEncoder"/>         
		</authentication-provider>
	</authentication-manager>

</beans:beans>

✅ intercept-url

권한에따라 특정 URL에 대한 접근 제한을하는 역할입니다!!

  • pattern

    접근 제한을 설정할 URL 패턴을 지정합니다.

  • access

    접근 권한을 지정합니다.

    • hasRole : access 속성에 지정된 권한을 가진 사용자만 접근할 수 있도록 합니다.
    • hasAnyRole : access 속성에 지정된 권한 중 하나를 가진 사용자만 접근할 수 있도록 합니다.
    • permitAll : 모든 사용자의 접근을 허용합니다.
    • denyAll : 모든 사용자의 접근을 거부합니다.

✅ form-login

Spring Security의 로그인 인증을 하는 역할입니다!!

  • login-processing-url

    로그인 요청을 처리할 URL을 지정합니다.
    기본값은 /login 입니다.

  • username-parameter

    로그인 폼에서 사용자 ID를 입력받을 input 태그의 name 속성 값을 지정합니다.
    기본값은 username 입니다.

  • password-parameter

    로그인 폼에서 비밀번호를 받을 input 태그의 name 속성 값을 지정합니다.
    기본값은 password입니다.

  • default-target-url

    로그인이 성공하면 이동할 URL을 지정합니다.

  • authentication-success-handler-ref

    로그인이 성공하면 호출될 핸들러를 지정합니다.
    기본값은 org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler

  • authentication-failure-handler-ref

    로그인이 실패하면 호출될 핸들러를 지정합니다.
    기본값은 org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler

✅ logout

로그아웃은 따로 컨트롤러를 만들지 않아도 시큐리티 설정에서 간단하게 구현가능합니다.
이건 매우 장점....

<logout logout-url="/logout" logout-success-url="/post" invalidate-session="true" delete-cookies="JSESSIONID"/>

✅ Remember-Me

영구 토큰 접근 방식을 사용

security-context.xml 파일을 만들어서 한번에 관리하고 있는 설정이라 요소만 추가하면 사용할 수 있기 때문에 이 방식을 사용

<remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>

이 방식을 사용한다면 사용중인 데이터베이스에 persistent_logins 이름의 테이블이 생성되어 있어야합니다.

MySQL ver.

create table persistent_logins(
    username varchar(64) not null,
    series varchar(64) primary key,
    token varchar(64) not null,
    last_used timestamp not null
);

설정은 대부분 끝났고, 기존 @Controller, form 태그로 로그인하는 방식을
@RestController, ajax로 변경해보려고한다..
REST API 조건을 최대한 고려해보자! 하는 목적이고, 요청에대한 응답을 적절한 응답코드로 응답을 받을 수 있도록 Ajax를 사용해보자!!

참고
https://docs.spring.io/spring-security/site/docs/3.1.x/reference/remember-me.html

0개의 댓글