본문 바로가기
지식공유/Spring Security

스프링 시큐리티(Spring Security) 환경설정, 초기세팅(백엔드/개발/Java/인증 및 인가)

by 시간기억자 2024. 11. 10.
반응형

스프링 Security

 

  • Spring Security : 인증과 인가 기능을 제공하는 보안 프레임워크
  • 인증(Authentication) : 프로그램을 사용할 수 있는 사용자가 맞는지를 확인하는 절차
    → 인증을 정상적으로 수행하기 위해서는 사용자를 구분할 수 있는 정보 필요 - Credential
  • 인가(Authorization) : 인증된 사용자가 요청한 자원에 접근 가능한가를 결정하는 절차(권한이라고 생각하면 됨)
    → 인증 처리 후 권한을 부여 받을 수 있으며 권한은 일반적으로 역할(Role) 형태로 부여
    → 전처럼 인가를 위해 Interceptor를 만들 필요 없이 환경설정만 해주면 된다. 아니면 어노테이션을 이용해도 된다.
  • Spring Security는 인증과 인가를 위해 Principal 객체를 아이디로 사용하고 Credential 객체를 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용
    → Principal 객체에는 사용자의 모든 정보가 들어가 있다.

 

환경설정

 
  • 프로젝트 생성(Spring Legacy Project)
  • 프로젝트 properties에서 project facets 수정

  • pom.xml은 spring 프로젝트꺼 복붙하기
  • log4jdbc.log4j2.properties 파일도 spring 프로젝트꺼 복사해서 src/main/resources/ 경로에 붙여넣기


Spring Security를 SpringMVC 프로그램에 적용하는 방법

  • spring-security-web, spring-security-core, spring-security-config, spring-security-taglibs 라이브러리를 프로젝트에 빌드 처리 - 메이븐 : pom.xml
    → 4개의 라이브러리 모두 5.X.X 대 버전 사용(6.X.X대 버전은 JDK17 버전에서 사용)

1. spring-security-web
  • 역할: 웹 애플리케이션의 보안을 위한 기능을 제공합니다.
  • 기능:
2. spring-security-core
  • 역할: Spring Security의 핵심 기능을 제공합니다.
  • 기능:
3. spring-security-config
  • 역할: Spring Security의 설정을 간편하게 관리할 수 있도록 도와줍니다.
  • 기능:
4. spring-security-taglibs
  • 역할: JSP와 같은 뷰에서 보안 관련 태그를 사용할 수 있게 해줍니다.
  • 기능:
이렇게 각 라이브러리는 Spring Security의 다양한 기능을 제공하여 웹 애플리케이션의 보안을 강화하는 데 기여합니다.

 

  • [web.xml] 파일에 Spring Security 기능을 제공하는 필터 클래스를 필터로 등록하고 필터가 실행되기 위한 URL 패턴을 매핑 처리
<!-- DelegatingFilterProxy 클래스를 필터로 등록되도록 설정 -->
<!-- => 반드시 필터의 이름을 [springSecurityFilterChain]으로 등록되도록 작성해야 한다. -->
<!-- DelegatingFilterProxy : 메인 Filter Chain에 위치되도록 설정하는 클래스 -->
<!-- => Spring Security 필터를 사용하는 시작점으로 설정되며 서블릿 컨테이너(WAS)의 필터와 ApplicationContext(Spring Container)에서 Spring Bean으로 등록된 필터를 연결하는 다리 역할 수행 -->
<!-- => 사용자가 웹프로그램을 요청하면 DelegatingFilterProxy 필터가 요청을 받아 FilterChainProxy 필터에게 요청을 위임하여 필요한 필터들이 순서대로 실행되도록 동작 →

DelegatingFilterProxy 얘 하나만 필터로 등록하면 다른 필터와 연결이 된다. 
(DelegatingFilterProxy 얘 하나만 필터로 등록하면 다른 여러가지 필터를 사용해서 인증과 인가를 해주는 것이라고 생각하면 된다.)

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

 

  • [web.xml] 파일에 Spring Security 기능의 필터를 사용하기 위한 정보를 제공하는 Spring Bean  Configuration File 설정 - ContextLoaderListener 클래스가 읽을 수 있도록 파일 경로 지정
    → context-param 엘리먼트로 작성
    → security-context.xml : spring security 관련 spring bean을 등록하는데 사용하거나, 필터에 필요한 정보를 제공할 수 있다.
    → security-context.xml <beans>엘리먼트 속성 값 순서 변경

  • namespace 3개 추가 : beans / context / security
<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 https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
</beans:beans>

  • 기본적으로 beans namespace를 기본 namespace로 사용하는데, Spring Security에서는 security를 namespace로 설정해야 사용하기 편해서 그렇게 변경 설정을 해줘야 한다.
    (꼭 이렇게 쓸필요는 없지만 권장사항이다)
  • 기본 네임스페이스를 [security]로 설정하여 사용하는 것을 권장
  • [security] 네임스페이스의 spring-security.xsd 파일에서 제공하는 다수의 엘리먼트 사용하기 때문에.

 

  • Spring Security 기능을 구현하기 위한 Spring Bean Configuration File 작성
 
  • http : Spring Security 기능을 SpringMVC 프로그램에 적용하기 위한 정보를 제공하는 엘리먼트
    (이거는 무조건 있어야 한다. 이거 없으면 Spring Security가 제공하는 필터를 사용할 수 없다)
    → Spring Security 관련 환경 설정이 시작되는 위치를 제공
  • auto-config : false 또는 true(기본값) 중 하나를 속성값으로 설정
    → auto-config 속성값을 [true]로 설정한 경우 기본값으로 환경 설정
  • use-expressions : false 또는 true(기본값) 중 하나를 속성값으로 설정
    → use-expressions 속성을 [true]로 설정하면 SpEL 표현식을 사용하여 페이지 접근 여부 설정 가능
    → use-expressions 속성을 [false]로 설정하면 SpEL 표현식을 사용불가능
  • SpEL 표현식(Spring Expression Language) : 권한을 표현하는 표현식
    → hasRole('role') : 권한을 가지고 있는 경우를 나타내는 표현식
    → hasAnyRole('role1','role2',...) : 나열된 권한 중 하나를 가지고 있는 경우를 나타내는 표현식
    → permitAll : 모든 사용자의 접근 가능을 나타내는 표현식
    → denyAll : 모든 사용자의 접근 불가능을 나타내는 표현식
    → isAnonymous() : Anonymous 사용자(인증 받지 않은 사용자)인 경우에만 접근 가능을 나타내는 표현식
    → isRememnberMe() : Remember-me 기능으로 인증받은 사용자인 경우에만 접근 가능을 나타내는 표현식 →
    → isAuthentucated() : 인증 처리된 사용자(Remember-me 기능으로 인증받은 사용자 포함)인  경우에만 접근 가능을 나타내는 표현식
    → isFullyAuthenticated() : 인증 처리된 사용자(Remember-me 기능으로 인증받은 사용자 제외)인 경우에만 접근 가능을 나타내는 표현식

  • 이런 SpEㅣ 표현식은 interceptor-url에서 써야 한다.

  • use-expressions 속성을 [false]로 설정한 경우 access 속성값으로 SpEL 사용 불가능
  • intercept-url 엘리먼트를 사용해 페이지에 접근 가능한 권한을 하나만 설정 가능
  • intercept-url : 요청 페이지에 접근 가능을 권한을 설정하는 엘리먼트
    → 특정 페이지에 대한 권한 설정을 먼저하고 나머지는 마지막에 설정하는 것을 권장
  • pattern 속성 : 요청 페이지의 경로를 속성값으로 설정
    → * 또는 ** 등의 패턴문자를 사용하여 속성값 설정 가능
    → * : 폴더에 있는 페이지까지
    → ** : 하위폴더까지에 있는 페이지까지
access 속성 : 페이지에 접근 가능한 권한(Role)을 속성값으로 설정
→ use-expressions 속성을 [true]로 설정한 경우 SpEL를 사용해 권한 설정 가능
→ 권한이 없는 사용자가 페이지를 요청할 경우 AccessDeniedException 발생
  • form-login : form 태그를 사용한 로그인 페이지를 설정하기 위한 엘리먼트
  • login-page 속성 : 아이디와 비밀번호를 입력받기 위한 페이지의 경로를 속성값으로 설정
    → 속성을 설정하지 않은 경우 Spring Security에서 제공하는 로그인 페이지 사용
login-processing-url 속성 : 아이디와 비밀번호를 전달받아 인증 처리하는 페이지의 경로를 속성값으로 설정
  • authentication-manager : 인증 관리자를 등록하기 위한 엘리먼트
    →  다양한 형태의 인증 방식 제공
  • authentication-provider : 인증 제공자를 등록하기 위한 엘리먼트
    → 실질적인 인증 작업을 진행하는 기능 제공
  • user-service : 인증 정보를 등록하기 위한 엘리먼트
    → 인증 처리를 이용해 사용자의 권한 관련 정보를 반환하는 기능
  • user : 인증을 위한 정보 및 사용자의 권한 정보를 설정하는 엘리먼트
  • name 속성 : 사용자를 구분하기 위한 식별자(아이디)를 속성값으로 설정
  • password 속성 : 사용자의 비밀번호를 속성값으로 설정
    → Spring Security 5.0 이상에서는 비밀번호를 반드시 암호화 처리하여 비교되도록 구현
    → password 속성값으로 설정된 비밀번호 앞부분에 {noop}를 붙여 작성하면 암호화 처리 하지 않아도 비교
  • authorities 속성 : 권한(Role)을 속성값으로 설정
    → 권한은 ROLE 기반으로 설정 - 속성값을 ROLE_XXX 형식으로 설정
    → 사용자에게 다수의 권한을 제공할 경우 , 기호로 구분하여 권한을 나열해 설정 가능
  •  인증이 성공한 경우 Authentication Manager는 Spring Security 관련 세션(Security ContextHolder)에 인증 및 인가 관련 정보(Authentication 객체) 저장
  • jdbc-user-service : Spring Security가 JDBC를 이용해 인증 처리하기 위한 엘리먼트
    →  JdbcUserDetailsManager 클래스를 사용해 인증과 인가 처리
    → USERS 테이블을 생성해 사용자 정보를 저장하고 AUTHORITIES 테이블을 생성하여 사용자의 권한 정보를 저장할 경우 SQL 명령을 작성하지 않아도 기본적으로 제공되는 SQL 명령으로 인증 처리 후 사용자 정보(UserDetails 객체)를 반환
    UserDetails 객체에는 아이디, 비밀번호, enabled 정도의 인증정보와 인가정보만 가지고 있다. 그런데 이것뿐만 아니라 사용자 전체 정보를 저장하고 싶으면 별도의 클래스(CustomUserDetails)를 만들어줘야 한다.
    → 인증하려면 SQL 명령이 필요한데 그걸 우리가 만들어주는게 아니라 알아서 만들어서 인증 진행을 해주는거다.
    → 사용자 정보(UserDetails 객체)는 세션에 저장되고 우리는 그걸 가져다가 요청 처리 메소드나 뷰에서 사용할 수 있다.
  • data-source-ref : Connection 객체를 제공하기 위한 DataSource 관련 클래스의 Spring Bean 식별자(beanName)을 속성값으로 설정
  • password-encoder : 암호화 처리된 비밀번호를 비교하기 위한 기능을 제공하는 엘리먼트
ref 속성 : PasswordEncoder 인터페이스를 상속받은 클래스의 Spring Bean 식별자(beanName)을 속성값으로 설정

 

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

 

 

Spring Security를 SpringMVC 프로그램에 적용하여 제공 받을 수 있는 기능
(필터를 사용해서 이 기능들을 제공한다고 생각하면 됨)
  • 다양한 형태(폼로그인 인증, 토큰 기반 인증, OAuth2 기반 인증, LDAP 인증)의 사용자 인증 방법 제공
    → OAuth2 기반 인증 : 다른 사이트에 인증을 요청하고 받는 것(예 : 카카오, 네이버 등)
    → LDAP 인증 : 인증을 할 수 있는 서버를 따로 만드는 것
  • 프로그램 사용자의 역할(Role)에 따른 권한 레벨 적용
  • 프로그램에서 제공하는 자원에 대한 접근 제어
  • 데이터 암호화 : CustomPasswordEncoder 인터페이스 상속받아 사용
  • SSL 적용
  • 일반적으로 알려진 웹보안 공격 차단

 

Spring Security Filter의 종류
  1. SecurityContextPersistenceFilter : SecurityContextRepository에서 SecurityContext를 가져오거나 생성하는 필터
  2. LogoutFilter : 로그아웃 요청을 처리하는 필터
  3. UsernamePasswordAuthenticationFilter : 아이디와 비밀번호를 사용하는 Form 기반 유저 인증을 처리하는 필터
    → Authentication 객체를 만들고 AuthenticationManager에게 인증 처리 위임
    → AuthenticationManager는 실질적인 인증에 대한 검증 단계를 총괄하는 AuthenticationProvider에게 인증 처리를 위임 - UserDetailService와 같은 서비스를 사용해서 인증 처리
  4. ConcurrentSessionFilter : 동시 세션과 관련된 필터 - 이중 로그인 방지
  5. RememberMeAuthenticationFilter : 세션이 사라지거나 만료 되더라도 쿠키 또는 DB를 사용하여 저장된 토큰을 기반으로 인증 처리하는 필터
  6. AnonymousAuthenticationFilter : 사용자 정보가 인증되지 않았다면 익명 사용자 토큰을 반환하는 필터
  7. SessionManagementFilter : 로그인 후 Session과 관련된 작업을 처리하는 필터
    → 여기에 권한관련 정보를 저장한다.
  8. ExceptionTranslationFilter : 필터 체인 내에서 발생되는 인증 및 인가 관련 예외를 처리하는 필터
  9. FilterSecurityInterceptor : 권한 부여와 관련한 결정을 AccessDecisionManager에게 위임해 권한 부여 결정 및 접근 제어를 처리하는 필터
  10.  HeaderWriterFilter: Request의 HTTP 헤더를 검사해 Header를 추가하거나 빼주는 필터
  11.  CorsFilter : 허가된 사이트나 클라이언트의 요청인지 검사하는 필터
  12.  CsrfFilter : CSRF Tocken을 사용하여 CSRF 공격을 막아주는 기능을 제공하는 필터


CommonsMultipartResolver 를 Spring 프로젝트에서는 servlet-context.xml에 등록했는데, Spring Security 프로젝트에서는 root-context.xml 에 등록을 해줘야한다.
Spring Security를 쓰면 multipart/form-data를 전달할때는 Spring Security의 영향을 받기 때문에 root-context.xml에 써야 하는 것이다.
servlet-context.xml에 등록하면 Spring Bean 인식을 못한다.

반응형

댓글