Spring Security를 개발하기위해 해당 관련 정보들을 학습하는도중 

일반적으로 사용되는 filer의 두가지에 대해 정리하려고 한다.

- AbstractAurhenticationProcessingFilter
- OncePerRequestFilter

 

 


포스트의 내용의 흐음은 아래와 같다.
  • 두가지 필터의 간단한 내용 요약
  • 차이점 
  • 결론

 

 

 

AbstractAurhenticationProcessingFilter


 

AbstractAurhenticationProcessingFilter를 매번 이름을 쓰기에는 너무 길기 때문에 AAPF로 명명하겠다

 

AAPF는  Spring Security에서 제공하는 기본 인증처리 필터이다

 

 

AAPF의 처리방식간단하게 정리하면 아래순서와 같다

  1. 사용자의 인증을 처리
  2. 인증의 처리가 성공된 경우 → Authentication 객체를 생성
  3. SecurityContextHolder에 생성된 Authentication의 정보를 저장한다

 

처리하는 로직? 상황? 을 통해 사용할 수 있는 방식도 정리해둔다!

  • 인증처리 → Authentication 객체 생성
  • 인증처리 실패 → AuthenticationFailureHandler를 이용해 실패처리를 수행할 수 있다. 
  • 인증처리 성공 → AuthenticationSuccessHandler를 이용해 성공처리를 수행할 수 있다

 

 

 

OncePerRequestFilter

 

 

OncePerRequestFilter의 경우  OPRF로 명명하겠다.

 

OPRF의 경우 모든 요청에 대해 한번만 실행하도록 보장된 필터이다.
→ 필터체인에서 딱한번만 실행되도록 보장된 필터라는 뜻

 

 

OPRF는 모든 요청에 공통적인 로직을 처리할 때에 유용하다고 한다.

ex) Spring Security와 JWT를 이용해 로그인을 구현 했다는 가정일 경우

모든 요청에서 JWT토큰을 검사해 유효성을 체크할 수 있음

 

 

 

 

 

차이점

 

AAPF와 OPRF는 용도가 다른 filter이기 때문에 차이점이라고 하기엔 모호하지만 

나는 이해하기 쉽게 차이점이라고 정리한다.

 

  • AAPF 인증을 처리하는데 사용하는 필터이고
  • OPRF 모든요청에 사용되는 필터이다

용도와 시점에 대해 정리해보면 각각의 어떤 용도로 사용되는 필터인지 좀 더 명확하게 이해할 수있다.

 

 

- 용도

AAPF    사용자의 인증처리하는데에 사용하며, 주로 로그인과 관련된 작업에 적합하다

OPRF  모든요청에 대해 공통적으로 수행되어야하는 작업에 적합

 

 

 

- 시점

AAPF 인증과정에서 특정한 시점에서 동작

OPRF 모든요청에서 수행되며 특정시점에 대한 제한은 없다.

 

 

 

 

결론

 

 

AAPF 로그인을 위한 로직에 관련된 기능을 수행하는 필터이고

OPRF 모든 요청에 대해 한번만 수행되는 필터이다

 

 

예시를 들면

AAPF  → 로그인을 수행할때 사용되는 필터

OPRF → 모든요청에서 토큰의 유효성을 체크하고 토큰의 유효성을 검사해 갱신하는 방식에 사용하는 필터

 

 

Spring Security의 경우 위의 AAPF와 OPRF의 필터를 기본적으로 사용한다고 하니 특별한 경우가 아닌 경우 두가지의 필터를 사용하면 될것같다.
특별한 경우는 나중에 찾아서 정리하는걸로....

 

 

나중에 Spring Security와 JWT를 이용한 코드를 작성하면서 해당 내용에 관련된 포스트를 올릴때 

해당 포스틑 언급하면서 나중에 봐도 알기 쉽게 사용할 수 있도록 정리하겠다.

 

 

[Spring Security] 스프링시큐리티 설정값들의 역할과 설정방법(2)

스프링시큐리티의 여러가지 설정값들의 역할과 설정방법을 상세히 알아봅니다. Spring Security 커스텀 필터를 이용한 인증 구현 - 스프링시큐리티 설정(2) 본 포스팅은 스프링시큐리티의 전반적인

kimchanjung.github.io

 

1. Spring Security란? 

스프링 시큐리티 (Spring Security)는 스프링 기반의 어플리케이션의 보안(인증과 권한, 인가)을 담당하는 스프링 하위 프레임워크.
보안과 관련해 체계적으로 많은 옵션들을 제공해주기 때문에 개발자의 입장에서는 하나하나 보안 관련 로직을 작성하지 않아도 된다는 장점이 있음.

 

 

1-1. Spring Security 관련 용어

  • 인증(Authentication) : 해당 사용자가 본인인지 확인하는 절차
  • 인가(Authorization) : 인증된 사용자가 요청한 자원에 접근 가능한지 결정하는 절차
  • 접근 주체(Principal) : 보호받는 Resource에 접근하는 대상
  • 비밀번호(Credential) : Resource에 접근하는 대상의 비밀번호
  • 권한 : 인증된 주체가 어플리케이션의 동작을 수행할 수 있도록 허락되어 있는지 결정
    • 인증 과정을 통해 주체가 증명된 이후 권한을 부여할 수 있다.
    • 권한 부여에 두 가지 영역이 존재하는데 웹 요청 권한과 메서드 호출 및 도메인 인스턴스에 대한 접근 권한 부여가 있다.



기본적으로
인증(Authentication)  → 인증성공 → 인가(Authorization)


Spring Security는 기본적으로 인증 절차를 거친 후에 인가 절차를 진행하게 되며, 인가 과정에서 해당 리소스에 대한 접근 권한이 있는지를 확인하게 됩니다. 이러한 인증과 인가를 위해 Principal을 아이디로, Credential을 비밀번호로 사용하는 인증 방식을 사용합니다.

 


기본적으로 인증 정보는 최종적으로 인메모리 세션 저장소인
SecurityContextHolder에 세션 - 쿠키 방식으로저장

 

 

 

 

2. Spring Security 동작원리

 

 

2-1 . Spring Security 동작원리 상세 (1~4)

동작원리의 1-4까지 흐름

1. 요청 (Request)
사용자가 로그인 정보를 요청한다.
예시) 로그인페이지에서 아이디와 비밀번호를 입력한다. 그럼 아이디와 비밀번호가 서버로 전송하게 된다.

AuthenticationFilter 는 사용자의 세션 ID(JSESSIONID)가 Security Context에 있는지 확인한다.
(여기서 Security Context란 아래의 모든 로직을 통과한 인증된 사용자의 정보(인증 개체)를 저장하는 공간이다.)
Security Context에 세션 ID가 없다면 아래 로직을 수행한다.

 


2. 토큰 생성

사용자가 보낸 아이디와 비밀번호를  AuthenticationFilter가 받아서 UsernamePasswordAuthenticationToken 토큰(인증용 객체)을 생성한다.

 AuthenticationFilter가 받고 아이디와 비번을 UsernamePasswordAuthenticationToken 토큰(인증용 객체)에 전달

 

 

3. 생성된 UsernamePasswordAuthenticationToken는 AuthenticationManager의 인증 메서드를 호출하는 데 사용된다.
여기서 AuthenticationManager는 단순한 인터페이스이며 실제 구현은 ProviderManager이다.

  • ProviderManager 에는 사용자 요청을 인증에 필요한 AuthenticationProvdier 목록이 있다.
  • ProviderManager는 제공된 각 AuthenticationProvdier를 살펴보고 전달된 인증 개체(UPAT)를 기반으로 사용자 인증을 시도한다.

※ UPAT  : UsernamePasswordAuthenticationToken는 너무길어서 여기부턴 UPAT로  명명하겠음

 


4. 토큰을 처리할 수 있는 AuthenticationProvider 선택
AuthenticationManager는 List 형태로 AuthenticationProvider들을 가지고 있는데, 실제로 인증을 할 AuthenticationProvider에게 인증용 객체를 다시 위임한다.
예시) AuthenticationManager는 인증을 담당하는 클래스이지만, 진짜는 AuthenticationManager가 가지고 있는 AuthenticationProvider 인터페이스들한테 "이거(인증용 객체) 줄테니 한번 인증처리가 가능한 AuthenticationProvider는 인증처리 해줘" 라고 또 떠넘기는 방식이다.

 

  • AuthenticationProvider의 리스트 중 일부
    • CasAuthenticationProvider
    • JaasAuthenticationProvider
    • DaoAuthenticationProvider
    • OpenIDAuthenticationProvider
    • RememberMeAuthenticationProvider
    • LdapAuthenticationProvider

 

 

2-2 . Spring Security 동작원리 상세 (5~7)

동작원리의 5~7까지 흐름

5. AuthenticationProvider는 사용자의 이름(username)을 기반으로 사용자의 세부정보를 검색하기위해 UserDetailsService를 사용할 수 있다.

 

 

5-1. AuthenticationProvider 인터페이스에서는 authticate() 메서드를 오버라이딩해 인증용객체를 파라미터로 받아 로그인페이지에서 입력한 사용자의 정보를 들고 올 수 있다. 

 

 

6, 7 . UserDetailsServiceDB에 저장된 회원의 비밀번호와 입력한 비밀번호가 일치하면 UserDetails인터페이스를 구현한 객체를 반환

UserDetailsService는 Spring Security의 인터페이스 이며 이를 구현한 서비스는 직접개발 해야한다.

즉, 아래 코드의 loadUserByUsername메소드를 오버라이딩해 DB와 비교하는 로직을 직접개발 해야한다.

public interface UserDetailService {
    UserDetail loadUserByUsername(String username) throws UsernameNotFoundException;
}

 

 

8. AuthenticationProvider 인터페이스에 의해 사용자가 성공적으로 인증되면, 완전히 채워진 인증개체가 반환된다.
인증에 실패하면 AuthenticaionException이 발생한다.
AuthenticaionException이 발생하면 인증 메커니즘을 지원하는 AuthenticationEntryPoint에 의해 처리된다.

사용자의 정보가 존재하지 않는경우 예외를 던진다고한다. (아래 코드 참고)

 

 

9. 인증완료

AuthenticationManager는 획득한 완전히 채워진 인증개체를 관련 인증 필터(AuthenticationFilter)로 다시 반환한다

 

 

10. SecurityContext에서 인증 개체 설정

AuthenticationFilter는 향후 필터 사용을 위해 획득한 인증 개체를 SecurityContext에 저장한다.

SecurityContext는 1번 로직에서 설명 했었다. 이 SecurityContext에 인증개체가 있는지를 확인하고, 

인증 로직이 수행되거나 수행되지 않는다.

SecurityContextHolder.getContext().setAuthentication(authentication);

 

 

 

각 Filter들의 역할

  • AuthenticationFilter
  • AuthenticationProvider
  • UserDetailsService
  • UserDetails

 

AuthenticationFilter

인증되지 않은 사용자와 인증된 사용자의 요청을 감시하고, AuthenticationManager에게 인증처리를 맡김
인증이 성공한다면 인증용 객체를 AuthenticationContext 객체에 저장하고 AuthenticationSuccessHandler 실행
실패 시 AuthenticationFailureHandler 실행

 

AuthenticationProvider

로그인페이지에서 입력한 정보와 DB에 저장된 정보를 비교
일치하다면 Authentication객체로 담아 AuthenticationManager에게 전달
만약 DB에 저장된 정보들 중 로그인페이지에서 입력한 정보와 일치하는 정보가 없다면 UsernameNotFoundException예외 처리

 

UserDetailsService

DB에서 유저정보를 가져오는 역할담당

 

UserDetails

사용자의 정보를 담은 인터페이스이며 직접 상속받아 사용한다.
유저객체에서 UserDetails를 상속받게 되면 구현해야할 메서드들이 있으며, 각 메서드들의 정의는 다음과 같다.

 

 

 

 

 

 

 

 

※ 참고 게시글 리스트 

 

 

[Spring Security] Spring Security의 개념과 동작 과정

📢 들어가기 전에 이번 포스팅에선 Spring Security가 무엇인지, 그리고 어떻게 동작하는 지에대해 알아본다. 인증, 인가, 보안 주체 Spring Security를 공부하기에 앞서 보안 용어에 대해 숙지해야한다.

doozi0316.tistory.com

 

 

Spring Security 동작 원리

Spring Security란 ? 스프링에서 제공하는 보안 관련 프레임워크다. 사용자의 요청에 대한 인증, 사용자가 권한이 있는지 확인하는 인가, 응답 등등 보안에 관련해서 많은 부분을 제공해주고 있기 때

skatpdnjs.tistory.com

 

spring_seurity의 설정 후 oauth2.0으로 kakao 로그인 기능으 구현했다.

 

 

그런데 카카오의 로그인 까지는 정상적으로 동작이 되지만 자꾸 리다이렉션이 발생한다는 내용이 브라우저에 표시되었다.

 

확인해 보니 spring security에서 사용하는 yml설정 중에 redirect-uri는 기본양식이 있다고 한다.

 

 

Spring Security + OAuth2.0 + JWT

✔︎ Spring Security + OAuth 2.0 Redirect URI Authorization server(Google, Kakao 등)에서 사용자 인증 후 리다이렉션할 URI이다. 쉽게 말해 타사 서비스에서 우리 서비스로 돌아올 수 있는 경로라고 생각하면 된다.

velog.io

아래의 양식으로 변경 해주니 정상적으로 동작했다.

 

 

기존

 - >

redirect-uri: http://localhost:8080/oauth2/login/kakao

 

수정후 

->

redirect-uri: http://localhost:8080/login/oauth2/code/kakao

Spring Security 의 사용방법 및 메소드 설명이 정리되어있는 블로그를 남겨둔다.

 

Spring Security 간단한 사용방법

📌 Intro 항해99 주특기 숙련주차에서 처음 Spring Security를 접하고 미니프로젝트 주차에서도 Spring Security를 접했다. 물론 숙련주차에서 작성한 코드를 기반으로 했지만 Spring Security는 너무 어렵다..

comclothing.tistory.com

 

사용 방법의 간단한 예제를 설명해주는 포스트가 있어 참고하기위해 남겨둔다.

 

Security 버전의 경우 5.7을 기준으로 작성된것으로 보이나 참고하면 도움이 될 것 같아 링크를 남겨둔다.

 

 

Spring Security 간단한 사용법

Spring Security 간단한 사용법

velog.io

 

스프링 시큐리티를 구현하기에 앞서 스프링 시큐리티가 동작하는 방식에 대해서 이해하면 시큐리티에 대해 더 깊이 학습할 때 도움이 될 것이다.

 

 

해당 내용은 링크를 참고 하도록 하자.

 

[Spring Security] 스프링시큐리티 기본개념과 동작구조의 이해(1)

스프링시큐리티의 기본개념과 동작구조 및 별도의 인증을 도입할 때 필요한 커스텀 필터를 작성하고 적용하는 방법을 알아봅니다” Spring Security 커스텀 필터를 이용한 인증 구현 - 스프링시큐

kimchanjung.github.io

 

Spring Security  내용 정리

해당 포스트는 Security를 공부하면서 내용을 정리하는 포스트 이다.

 

 

 

1. @EnableWebSecurity

- 해당 어노테이션은 스프링 시큐리티를 활성화 하고 웹보안 설정을 구성하는데 사용된다고한다.

-> spring Security 사용할거면 클래스의 상단에 @EnableWebSecurity를 선언해주자

 

하단의 내용의 경우 5.7 이전 버전의 내용이다.

=> 경우 extends를 통해 webSecurityConfigurerAdapter를 상속받아 오버라이딩하는 방식이다.

@EnableWebSecurity	// SecurityConfig로 시큐리티를 제어함.
public class SecurityConfig {
	// ...
}

 

하단의 내용은 6.x 버전부터의 내용이다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	// ...
}

 

=> 경우 extends를 통해 webSecurityConfigurerAdapter를 상속받아 사용하는 방식이 사라졌다.

 

- 바로아래 참고 블로그 링크를 남겨두었다

 

[Spring Security] 스프링 시큐리티 기초

** 스프링부트를 기준으로 작성되었습니다** 0. 스프링 시큐리티의 동작과 구조 스프링 시큐리티를 구현하기에 앞서 스프링 시큐리티가 동작하는 방식에 대해서 이해하면 시큐리티에 대해 더 깊

myvelop.tistory.com

 

 

하단은 Spring Security 6.x 버전의 내용

- 바로 아래 공식사이트 링크를 남겨두었다

 

Configuration Migrations :: Spring Security

In 6.0, @Configuration is removed from @EnableWebSecurity, @EnableMethodSecurity, @EnableGlobalMethodSecurity, and @EnableGlobalAuthentication. To prepare for this, wherever you are using one of these annotations, you may need to add @Configuration. For ex

docs.spring.io

 

Security 5.8에서 새로운 메소드가 추가되고

6.x버전에서는 이제 권장되지 않는 메소드는 메소드가 삭제되었다고 한다

 

삭제된 메소드

  • antMatchers()
  • mvcMatchers()
  • regexMatchers()

대체 메소드

  • requestMatchers()

 

6.1 버전 관련된 포스트가 있어 링크 걸어둔다 한번쯤 쓱 훑어 보는것이 좋을것같다.

 

Spring Security) Spring Boot 3.1.0, Spring 6.1, Spring Security 6.1

Springboot 3.1.0 환경에서 Spring Security로 인증 방식을 구현하던 중 FilterChain 등록 코드에서 deprecated 에러 사인이 등장했다. Spring Security 6.1.0 SpringBoot 3.1.0 버전은 Spring Security 6.1.0 버전을 dependency 한다.

byungil.tistory.com

 

 

 

공식 사이트에서 참고 예제를 올려 놓은 부분을 올려 둘테니 확인해보자

security를 맨땅에 헤딩을 하다보니

정확히 어떤동작을 하고  모르는 내용이 잔뜩 있으니 나중에 해당 내용의 상세 내용을 수정해야겠다.

 

 

 

 

 

 

webSecurityConfigurerAdapter 의 삭제로 인한 변경된 내용

  • SecurityFilterChain @Bean 게시
  • WebSecurityCustomizer @Bean 게시
  • AuthenticationManager @Bean 게시
  • JDBC 인증방법변경 - AuthenticationManagerBuilder .jdbcAuthentication 사용
  • 메모리 내 인증방법 변경 - AuthenticationManagerBuilder.inMemoryAuthentication 사용

-> JDBC 인증방법메모리내 인증방법의 경우 정리해두진 않았다 공식 사이트를 참조하자

 

 

- SecurityFilterChain @Bean 게시

삭제 이전버전

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authorize) -> authorize
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
    }

}

 

삭제 후 버전 (6.x)

@Configuration
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authorize) -> authorize
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
        return http.build();
    }

}

 

 

 

- WebSecurityCustomizer @Bean 게시

삭제 이전버전

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/ignore1", "/ignore2");
    }

}

 

삭제 후 버전 (6.x)

@Configuration
public class SecurityConfiguration {

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
    }

}

 

 

- AuthenticationManager @Bean 게시

삭제 이전버전

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .userDetailsContextMapper(new PersonContextMapper())
                .userDnPatterns("uid={0},ou=people")
                .contextSource()
                .port(0);
    }

}

 

 

삭제 후 버전 (6.x)

@Configuration
public class SecurityConfiguration {
    @Bean
    public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
        EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
            EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
        contextSourceFactoryBean.setPort(0);
        return contextSourceFactoryBean;
    }

    @Bean
    AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {
        LdapBindAuthenticationManagerFactory factory =
            new LdapBindAuthenticationManagerFactory(contextSource);
        factory.setUserDnPatterns("uid={0},ou=people");
        factory.setUserDetailsContextMapper(new PersonContextMapper());
        return factory.createAuthenticationManager();
    }
}

 

 

 

 

 

SecurityFilterChain의 내용

  • 기초 내용변경 예제
  • 클래스 경로에 Spring MVC가 있고 메소드를 사용하는 경우 
  • servletPath의 속성을 사용자 정의하는 경우 - 정리 하지않음 공식문서 참조하자
  • requestMatchers 문제 시  requestMatchers()으로 다시 antMatcher()으로 변경하는 경우
  • CSRF 구성을 사용자 정의하는 경우
  • HttpSecurity의 matcher() ->  securityMatcher()으로 변경됨
  • HttpSecurity의 RequestMatcher()구성에서 사용자 정의를 사용 (단일건, 다중건)의 경우
  • securityMatchers() 문제 시 requestMatcher()로  antMatcher()으로 변경하는경우

 

 

5.7버전

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .antMatchers("/api/admin/**").hasRole("ADMIN")
                .antMatchers("/api/user/**").hasRole("USER")
                .anyRequest().authenticated()
            );
        return http.build();
    }

}

 

6.1 버전

 

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/user/**").hasRole("USER")
                .anyRequest().authenticated()
            );
        return http.build();
    }

}

 

코드상으로 antMatchers -> requestMatchers로 대체 되었다.

 

- 클래스 경로에 Spring MVC가 있고 메소드를 사용하는 경우 

5.7버전

@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .mvcMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            );
        return http.build();
    }

}

 

6.1 버전

@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            );
        return http.build();
    }

}

코드상에선 @EnableWebMvc 어노테이션을 클래스 상단에 선언해주면 6.1이전의  mvcMatchers()의 기능을 대체하여 동작하는듯하다.

 

 

- servletPath의 속성을 사용자 정의하는 경우도 있지만 공식 자료를 참고하자

 

 

 - requestMatchers 문제 시  requestMatchers()으로 다시 antMatcher()으로 변경하는 경우

 -> 새로운 메소드에 문제가 있는경우 언제든 사용중이던 requestMatchers으로 다시 전환 할 수 있다고한다.

해당내용의 코드는 하단에 예제를 참고하자

import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
import static org.springframework.security.web.util.matcher.RegexRequestMatcher.regexMatcher;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .requestMatchers(AntPathRequestMatcher.antMatcher("/user/**")).hasRole("USER")
                .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/user/**")).hasRole("ADMIN")
                .requestMatchers(RegexRequestMatcher.regexMatcher(".*\\?x=y")).hasRole("SPECIAL") // matches /any/path?x=y
                .anyRequest().authenticated()
            );
        return http.build();
    }

}

코드상으로 봤을때 requsetMatchers의 파라미터 부분에서 antMatcher, regexMatcher를 선언할수 있는듯하다.

- regexMatcher의 경우 정규식을 통한 방법이라고한다.

 

위의 내용으로 구현할 수있는 리스트는 아래의 내용과 같다.

- 공식문서에서의 내용만 보고 작성한것으로 하단 말고 추가적으로 더 가능한지는 나중에 확인해 봐야겠다

  • AntPathRequestMatcher
  • RegexRequestMatcher

 

 

- CSRF 구성을 사용자 정의하는 경우

5.7버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf((csrf) -> csrf
            .ignoringAntMatchers("/no-csrf")
        );
    return http.build();
}

 

6.1 버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf((csrf) -> csrf
            .ignoringRequestMatchers("/no-csrf")
        );
    return http.build();
}

 

 

 

 

 

- HttpSecurity의 matcher 사용법 변경 ->  securityMatcher

 

5.7버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .antMatcher("/api/**", "/app/**")
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers("/api/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

 

5.8버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .securityMatcher("/api/**", "/app/**")
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers("/api/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

 

5.8부터는 HttpSecurity의 antMatchers(), mvcMatchers() 및 requestMatchers() 메소드가 더 이상 사용되지 않습니다.

대신 securityMatcher()가 추가되었다고 한다.

-> 혼동을 피하기 위해서라나?

 

 

 

- HttpSecurity의 RequestMatcher구성에서 사용자 정의를 사용하는 경우 -> 

 - 단일건, 다중건

 

 

단일건  5.7버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .requestMatcher(new MyCustomRequestMatcher())
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers("/api/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

public class MyCustomRequestMatcher implements RequestMatcher {
	// ...
}

 

단일건  5.8버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .securityMatcher(new MyCustomRequestMatcher())
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers("/api/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

public class MyCustomRequestMatcher implements RequestMatcher {
	// ...
}

 

단일건의 경우

해당 내용은 securityMatcher()를 사용해 사용자 정의를 사용하는경우 인데 

requestMatcher() -> securityMatcher() 로 바뀐것 말곤 차이가 없는듯하다.

 

 

다중건 5.7버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .requestMatchers((matchers) -> matchers
            .antMatchers("/api/**", "/app/**")
            .mvcMatchers("/admin/**")
            .requestMatchers(new MyCustomRequestMatcher())
        )
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

 

다중건 5.8버전

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .securityMatchers((matchers) -> matchers
            .requestMatchers("/api/**", "/app/**", "/admin/**")
            .requestMatchers(new MyCustomRequestMatcher())
        )
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

 

다중건의 경우 단일건과 차이를 정리한 리스트는 아래 있다.

  • 단일건 : securityMatcher
  • 다중건 : securityMatchers
  • 다중건의 경우 securityMatchers를 람다표현식을 통해 다중으로 구현

 

 

- securityMatchers() 문제 시 requestMatcher()로  antMatcher()으로 변경하는경우

import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .securityMatchers((matchers) -> matchers
            .requestMatchers(AntPathRequestMatcher.antMatcher("/api/**")
            	, AntPathRequestMatcher.antMatcher("/app/**"))
        )
        .authorizeHttpRequests((authz) -> authz
            .requestMatchers(AntPathRequestMatcher.antMatcher("/api/admin/**")).hasRole("ADMIN")
            .anyRequest().authenticated()
        );
    return http.build();
}

 

 

 

 

 

 

WebSecurityCustomizer 

5.7버전

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}

 

6.1 버전

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
	return (web) -> web.ignoring().requestMatchers("/ignore1", "/ignore2");
}

antMatchers -> requestMatchers로 변경

+ Recent posts