Spring Security

김주언·2022년 10월 23일
0

Spring

목록 보기
15/15
post-thumbnail

스프링 시큐리티

스프링 시큐리티는 스프링 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크

기본용어

  • principal (접근주체) : 보호된 리소스에 접근하는 대상
  • authentication (인증) : 보호된 리소스에 접근한 대상에 대해 누구인지, 애플리케이션의 작업을 수행해도 되는 주체인지 확인하는 과정
    • 예를 들어 폼을 기반으로 하는 로그인
  • authorization (인가) : 해당 리소스에 대해 접근 가능한 권한을 가지고 있는지 확인하는 과정. 즉 인증 이후의 과정이다. 어떤것을 할 수 있는지 결정한다.
  • 권한 : 어떠한 리소스에 대한 접근 제한. 모든 리소스는 접근 제어 권한이 걸려 있으며, 인가 과정에서 해당 리소스에 대한 제한된 최소한의 권한을 가졌는지 확인한다.

username : 유저ID

series : 동일한 유저일 경우 브라우저별로 구분할 고유 값

   크롬과 익스플로러에서 동일한 유저가 두 브라우저에서 자동로그인을 체크하고 로그인하면,

   두 개의 row가 insert 됨. 그래서, 이런 경우의 구분을 위해서 고유한 series값을 사용함

   이렇게 신규 발급이 된 이후부터는 series 값으로 사용자 정보를 검색

   ⇒ token 값을 새로 발행 ⇒ persistent_logins taable에서 series 값으로 검색한 후,

   새로 발행된 token 값으로 update

token : 브라우저가 가지고 있는 쿠키의 값을 검증할 인증값

다시 브라우저에서 접속을 하면, 자동 로그인이 설정이 되었는지 확인

remember-me 쿠키(series:token)값을 복호화

series 값으로 token 값을 검색 → 동일하다면, 새로운 token 값을 발행해서 table에 update함

브라우저의 remember-me 쿠키 값을 갱신함

last_used : 마지막으로 로그인한 시간정보

security:remember-me의 token-validity-seconds 속성 관련

token-validity-seconds + last_used : 유효시간

로그인 시 현재 서버의 시간보다 유효시간이 이전이면→ 유효. 자동로그인 됨

이후이면→ 무효. 자동로그인 안됨

동작 방식

기본 동작 방식 : 서블릿의 여러 종류의 필터 + 인터셉터를 이용한 처리

시큐리티 필터

스프링 시큐리티를 알기 위해서는 서블릿 필터로 개발한 시큐리티 필터에 대한 이해가 필요하다.

서블릿 필터는 클라이언트의 요청을 가로채서 서블릿이 수행되기 전후에 전처리와 후처리를 수행하거나 요청을 리다이렉트하는 용도로 사용한다.

일반적으로 필터 한 개당 하나의 기능을 처리하기 때문에 여러 기능이 필요한 경우에는 여러 개의 필터를 만들어 필터 체인을 형성하여 사용한다.

스프링 시큐리티는 수많은 필터를 제공하는데, 각 필터들이 시큐리티 처리를 위한 기능을 제공하며 상호작용한다.

UsernamePasswordAuthenticationFilter

스프링 시큐리티를 구성하는 필터 중 가장 중요한 필터
사용자가 입력한 인증 정보를 이용하여 실제로 인증을 처리하는 필터이다.

FilterSecurityInterceptor

인증에 성공한 사용자가 해당 리소스에 접근할 권한이 있는지를 검증한다.

여러가지 필터들 중 인증 관리 필터와 권한 관리 필터가 인증과 인가를 처리하는 과정

  1. 사용자의 리소스 요청

  2. 인증 관리 필터가 사용자 요청을 가로챔
    2.1 인증 처리 관련 필터를 사용하여 사용자 인증을 처리하기 시작
    2.2 인증되지 않은 사용자의 접근 시 인증에 필요한 정보를 요청
    2.3 사용자의 인증 정보 입력
    2.4 파일 또는 DB에서 사용자 정보를 읽어 인증 정보를 검증

  3. 인증 통과 시 사용자가 요청한 리소스로 요청 전달

  4. 권한 관리 필터의 요청 가로채기
    4.1 리소스에 대한 접근 권한 검증
    4.2 리소스별 권한 목록 참조하여 접근 권한 검증한다.

필터와 인터셉터는 특정한 서블릿이나 컨트롤러의 접근에 관여한다는 점에서 유사하다.차이점은 필터는 스프링과 무관하게 서블릿 자원이고, 인터셉터는 스프링의 빈으로 관리되면서 스프링의 컨텍스트 내에 속한다는 점

일반 필터의 경우, 현재 실행되는 서블릿 컨텍스트에서 속하기는 하지만 스프링과는 무관하다.  
반면 인터셉터의 경우 스프링의 빈으로 관리되면서 스프링의 컨텍스트 내에 속하게 되어 스프링 내부에서 컨트롤러를 호출할 때 관여하기 때문에 스프링의 컨텍스트 내의 모든 자원을 활용 가능하다

사용자 정의 UserDetailsService

사용자가 시스템의 리소스에 접근하기 위해서는 가장 먼저 인증 관리 필터의 검증을 통과해야 한다.

인증관리 필터가 사용자의 입력 정보를 기반으로 인증 처리를 하기 위해서는 사용자 정보가 저장된 객체가 필요한데, 이 때 사용되는 객체가 UserDetails 객체이다.
또한, UserDetails 객체에 실제 데이터베이스에서 검색한 사용자 정보를 저장하기 위해서는 UserDetailsService 객체가 필요하다

인증 관리자는 UserDetailsService 객체를 통해 UserDetails 객체를 획득하고, 이 UserDetails 객체에서 인증과 인가에 필요한 정보들을 추출하여 사용한다.


설정

개발 환경

  • MacOS
  • IntelliJ

pom.xml에 의존성 추가

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

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>5.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>5.7.3</version>
        </dependency>

버전은 스프링 프레임워크랑 호환되도록 맞춰주고, 시큐리티끼리는 동일 버전 사용하도록 설정해준다.

security-context.xml

스프링 시큐리티는 단독 설정이 가능해서 설정 파일을 따로 빼두는 것이 관리하기 편하다.
root-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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">

    <security:http>
        <security:form-login/>
    </security:http>
    <security:authentication-manager />
</beans>

web.xml

스프링 시큐리티가 스프링 MVC에서 사용되기 위해서는 필터를 이용해서 스프링 동작에 관여하도록 해둔다.


<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>
<!-- ... 생략 ... -->
    <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>

그리고 필터이름 꼭 저렇게 맞춰야한다.. 아니면 못 찾음... 샹 ㅋㅋ


사용 예제

URI 설계

URI설명
/sample/all모두 접근 가능
/sample/member로그인한 사용자만 접근 가능
/sample/admin로그인 한 사용자 중 관리자 권한을 가진 사용자만 접근 가능

SampleController 작성

package com.board.controller;

import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Log4j2
@RequestMapping("/sample/*")
@Controller
public class SampleController {

    @GetMapping("/all")
    public void doAll(){
        log.info("SampleController - doAll can access everyone");
    }

    @GetMapping("/member")
    public void doMember(){
        log.info("SampleController - doMember can access member");

    }

    @GetMapping("/admin")
    public void doAdmin(){
        log.info("SampleController - admin");

    }
}

컨트롤러 작성 후 각 메서드와 일치하는 JSP 파일을 생성한다. (WEB-INF/views/sample/ ... )

로그인 & 로그아웃

접근 제한 설정

security-context.xml

    <security:http>
        <security:intercept-url pattern="/sample/all" access="permitAll"/>
        <security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
        <security:form-login/>
    </security:http>
  • <security:intercept-url />
    • 특정 URI 접근 시 인터셉터를 이용하여 접근을 제한한다.
    • pattern : URI 패턴
    • access : 권한 확인

설정 후 /sample/member로 이동하면 로그인 페이지로 이동된다. (스프링 시큐리티의 기본 로그인 페이지)

profile
학생 점심을 좀 차리시길 바랍니다

0개의 댓글