스프링 시큐리티 권한 부여

Tech/Java 2023. 1. 1. 18:11
728x90
728x90

문득 점프 투 스프링부트 교재를 공부하다 시큐리티는 인증과 권한을 담당한다는 문구를 보고

관리자같은 권한을 따로 부여하는 방법이 궁금해졌다.

 

해당 글은 스프링 시큐리티 - 점프 투 스프링부트(게시판 만들기) 편과 연계된다.

 

만들어 놓았던 SecurityConfig를 살펴보자.

package com.example.board.practice;

(... 생략 ...)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests().requestMatchers(
            new AntPathRequestMatcher("/**")).permitAll()
                .and()
                    .csrf().ignoringRequestMatchers(
                    new AntPathRequestMatcher("/h2-console/**"))
                .and()
                    .headers()
                    .addHeaderWriter(new XFrameOptionsHeaderWriter(
                    XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))

                .and()
                    .formLogin()
                    .loginPage("/user/login")
                    .defaultSuccessUrl("/")

                .and()
                    .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
                    .logoutSuccessUrl("/")
                    .invalidateHttpSession(true)
        		;
        
        return http.build();
    }
	(... 생략 ...)
}

 

http.authorizeHttpRequests().requestMatchers(new AntPathRequestMatcher("/**")).permitAll();

해당 문장은 [ localhost:8080/~~ ] URL이하 어떠한 주소가 달려도 모두에게 접근권한을 준다는 의미였다.

 

맞게 이해한 건지 확인을 위해 **을 빼고 들어가자 로그인창이 떳다.

 

관리자일 때만 해당 페이지에 들어가지게 만들고 싶었다.

(... 생략 ...)
http.authorizeHttpRequests().requestMatchers(
                new AntPathRequestMatcher("/")).permitAll()
        	.antMatchers("/question/detail/**").hasRole("ADMIN")
        		.and()
        		.csrf().ignoringRequestMatchers(
        				new AntPathRequestMatcher("/h2-console/**"))
                        
                        
	(... 생략 ...)

antMachers("해당 주소").hasRole("ADMIN") 코드를 작성하였다

 

성공한 것 같다

 

 

로그인을 했음에도 ADMIN이 아니기 때문에 페이지에 접근 불가능한 모습이다.

403 Forbidden

이 에러는 서버 자체 또는 서버에 있는 파일에 접근할 권한이 없을 경우에 발생한다. 서버에는 외부 접근을 제어하기 위한 수많은 권한 설정이 있고, 서버에서 설정해 둔 권한과 맞지 않는 접속 요청이 들어오면 접근을 거부하고 접근거부 코드를 반환하는데, 이 때 뜨는 것이 바로 403 Forbidden 에러다.

 

 

권한 설정 및 로그인, 로그아웃 그리고 403 Forbidden의 핸들링 처리를  보통 아래와 같이 한다고 한다.

protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        // 페이지 권한 설정
        .antMatchers("/admin/**").hasRole("ADMIN")
        .antMatchers("/user/myinfo").hasRole("MEMBER")
        .antMatchers("/**").permitAll()
    .and() // 로그인 설정
        .formLogin()
        .loginPage("/user/login")
        .defaultSuccessUrl("/user/login/result")
        .permitAll()
    .and() // 로그아웃 설정
        .logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
        .logoutSuccessUrl("/user/logout/result")
        .invalidateHttpSession(true)
    .and()
    // 403 예외처리 핸들링
    .exceptionHandling().accessDeniedPage("/user/denied");
    }
}

 

 

뷰단에서(템플릿) 이런식으로의 활용도 가능하다고 한다.

<a href="members/login" sec:authorize="isAnonymous()">로그인</a>
<a href="members/new" sec:authorize="isAnonymous()">회원가입</a>
<a href="members/logout" sec:authorize="isAuthenticated()">로그아웃</a>
<a href="util/find" sec:authorize = "hasRole('USER')">찾아보기</a>
<a href="util/register" sec:authorize = "hasRole('ADMIN')">등록하기</a>

해당 앵커 태그들은 권한에 따라 이동하는 링크가 다르게 셋팅되어있다.

 

 

 

시큐리티 표현식


스프링 시큐리티에서의 표현식은 아래와 같다. 하나 유의할 점은 isAnonymous()의 경우 anonynous 인증 객체를 가진 상태이기 때문에, 일반 유저로 로그인하여 Role_USER 권한을 가진 경우 접근이 불가하다. 모든 사용자가 접근이 가능하도록 만들고 싶다면, permitAll을 해야한다.

 

표현식 설명
hasRole(String role) 해당 롤을 가지고 있는 경우 true
hasAnyRole(String… roles) 해당 롤 중에 하나를 가지고 있는 경우 true
isAnonymous() 익명 사용자인 경우 true
isRememberMe() Remember Me 인증을 통해 로그인한 경우 true
isAuthenticated() 이미 인증된 사용자인 경우 true
isFullyAuthenticated() Remember Me가 아닌 일반적인 인증 방법으로 로그인한 경우 true
permitAll 항상 true
denyAll 항상 false
principal 인증된 사용자의 사용자 정보(UserDetails 구현한 클래스의 객체) 반환
authentication 인증된 사용자의 인증 정보**(Authentication** 구현한 클래스의 객체) 반환

 

 

 

 

참조

https://whitepro.tistory.com/481?category=1058993

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

방명록