공부해본 Filter 를 가지고 SecurityConfig 설정하기

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

이렇게 따로 클래스를 작성해 SpringSecurity 관련 설정을 이 클래스에서 하면 된다.

@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

가장 기본적으로 SecurityFilterChain 타입을 반환하는 filterchain 메소드를 생성해 메소드체이닝 기법으로 설정을 하면 된다.

설정 방법 알아보기

필터 Off

원하는 필터를 Off 하고 싶을때 사용한다.
.disable() 메소드로 off 할 수 있다.
(이미 비활성화 되어있어도 사용하지 않을 필터를 명시적으로 disable 하는 것도 좋은 방법이다.)

로그인 & 로그아웃 페이지 관련 기능

.formLogin().loginPage() 로 로그인 페이지를 지정하고, defaultSuccessUrl로 로긍니에 성공할시에 이동할 url 을 지정해준다.
로그아웃도 마찬가지이다.

Url Matchers 관련 기능

antMatchers

해당 url 요청을 모두에게 허용해준다.
(따로 인증 인가를 받지 않아도 접근이 가능하다.)

mvcMatchers

http.authorizeRequests().mvcMatchers("/login).permitAll()

유사 login 요청을 모두에게 허용한다. (/login 으로 시작하는 모든 요청을 허용한다.)

regexMatchers

정규 표현식으로 매칭한다.

requestMatchers

명확하게 요청 대상을 지정하는 경우에 requestMatchers 를 사용한다.

인가 관련 설정

authorizeRequests()

인가를 설정한다.

permitAll()

해당 url 에 대한 요청을 모두에게 허용한다.

hasRole()

권한을 검증한다.

/admin 에 대한 요청은 Admin 권한을 가진 계정만 허용해준다는 뜻을 가지고 있다.

authenticated()

인증이 되어있는지를 검증한다.

Ignoring

특정 리소스에 대해서 SpringSecurity 자체를 적용하지 않고 싶을때 사용한다.

permitAll과 다르게 완전히 SpringSecurity의 대상에 포함되지 않는다.
(어떠한 필터도 실행되지 않기 때문에 permitAll() 를 사용한 필터체인보다 ignoring() 을 사용한 코드가 성능적으로 우수하다.)

직접 SpringSecurityConfig 작성해보기

@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.httpBasic().disable()
                        .authorizeRequests().antMatchers("/login","/","/signup").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .mvcMatchers("/articles/post","/articles/put","/articles/delete").hasRole("USER")
                .and()
                .anonymous().principal("anonymousUser").authorities("ROLE_ANONYMOUS")
                .and()
                .rememberMe().and()
                .csrf().ignoringAntMatchers("/h2-console/**")
                .and()
                .headers()
                .addHeaderWriter(new XFrameOptionsHeaderWriter(
                        XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/")
                .invalidateHttpSession(true)
        ;
        return http.build();
    }

현재 내가 따로 토이프로젝트에 사용하고있는 설정은 이와 같다.

basicAuthenticationFilter와 antMatchers

basicAuthenticationFilter 는 내 프로젝트에서 굳이 사용할 필요가 없으니 disable 로 명시를 해주었다.

그리고 기본적으로 프로젝트상에서 로그인을 안했을시에 접근이 가능한 것들은

게시글 전체 조회 와 로그인화면 , 회원가입화면 이다.

따라서

 .authorizeRequests().antMatchers("/login","/","/signup").permitAll()

를 활용해 해당 부분에는 모두가 접근이 가능하도록 설정해주었다.

antMatchers 와 hasRole

그리고 UsernamePasswordAuthentiactionFilter 를 통해 인증 과정을 마치고, 인가순서때 내가 원하는 아이디는 ADMIN 이라는 권한과 USER권한을 주도록 했다.

따라서

.antMatchers("/admin/**").hasRole("ADMIN")
                .mvcMatchers("/articles/post","/articles/put","/articles/delete").hasRole("USER")

로 유저 권한을 가진 상황에서만 게시글 등록, 수정, 삭제를 할 수 있게 인가를 해줬고, 추후에 만들어볼 관리자 페이지또한 관리자 권한을 가진 상황에서만 접근할 수 있게 설정해주었다.

annonymous()

원래는 로그인을 하지 않은 상황에서 게시글이나 회원가입 폼에 접근하면 null인 상태로 접근이 되었는데, 그래도 해당 접근자가 어떤 권한을 갖고있는지 빈틈이 없게 하기 위해서

.anonymous().principal("anonymousUser").authorities("ROLE_ANONYMOUS")

를 선언해주었다.

.rememberMe()

로그인 유지 기능을 추가해보았다.

h2콘솔 접근을 위한 메소드

.csrf().ignoringAntMatchers("/h2-console/**")
                .and()
                .headers()
                .addHeaderWriter(new XFrameOptionsHeaderWriter(
                        XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))

Spring Security와 h2-console 함께 쓰기

devtools 를 사용하기 위해서 해줘야할 인증 면제처리들이다.

해당 글을 참고하면 좋다 :D

로그인을 위한 메소드

                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/")

따로 로그인 페이지를 지정하지 않고 기존에 스프링 시큐리티에서 기본으로 정해져이는 /login url 을 그대로 사용해 해당 메소드들을 선언하고, 유저 컨트롤러 또한 /login 을 입력시에 폼을 출력하도록 GetMapping 을 해주었다.

해당 필터체인메소드를 사용하면 내가 따로 로그인 기능을 구현하지 않아도 쉽게 추가가 가능하다.

                .invalidateHttpSession(true)
        ;
        return http.build();

로그아웃이 되면, 세션을 종료시켜준다.

그리고 해당 연결된 메소드들을 build 로 http객체로 리턴시켜준다.

단순히 http. 어어쩌구; http. 어쩌구구; 이렇게 작성하는법도 있지만, 나는 그냥 간단하게 쭈우욱 연결되도록 작성해보았다.

다음 글에는 jwt 토큰에 대해서 알아보도록 하자.

profile
자스코드훔쳐보는변태

0개의 댓글