728x90

개요

프로젝트 중 관리자 부분도 하기로 해서 구현해보고자 한다.

 

일단 관리자와 일반 유저를 나눴기 때문에 권한에 따라 접근할 수 있는 경로는 
1. SecurityConfig.java 에서 hasRole or hasAuthority 를 통해 접근 경로를 제한한다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    // 모든 유저 허용 페이지
    String[] allAllowPage = new String[] {
            "/",  "/de",      // 메인페이지
            "/signup", // 회원가입 페이지
            "/login", // 로그인 페이지
    };

    // 관리자 페이지
    String[] adminAllowPage = new String[] {
            "/admin",
            "/admin/**"
    };

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeRequests(authorize -> authorize
                        .requestMatchers(allAllowPage).permitAll()
                        .requestMatchers(adminAllowPage).hasRole("ADMIN")
                        .anyRequest().authenticated()
                )
                .addFilterBefore(new RedisJwtFilter2(jwtUtil, jwtBlacklistService, refreshTokenService), UsernamePasswordAuthenticationFilter.class)
                .formLogin(form -> form.disable());
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
 
    }

코드가 길어져서 불필요한 코드는 삭제했다. 

일단 나는 DB에
ROLE_ADMIN, ROLE_USER 형태로 사용자를 나눠서 저장했기 때문에 hasRole를 사용했다.

 

hasRole  과 hasAuthority 의 차이

  • hasAuthority
    • 권한을 부여할 때 역할이 아니라 권한 자체를 기준으로 접근을 제어
    • 직접 권한을 설정
    • hasAuthority("ROLE_ADMIN") 형태로 권한을 정확하게 명시해줘야 한다.
  • hasRole
    • 내부적으로 ROLE_ 접두사를 자동으로 붙인다.
    •  HTTP 요청 URL 패턴에 대해 접근 권한을 설정
    • 그래서 DB에 ROLE_ADMIN이라고 명시되어 있기 때문에 hasRole("ADMIN")이라고 명시를 한다.
@Controller
@RequiredArgsConstructor
public class AdminController {

    private final UserService userService;
    private final JwtTokenizer jwtTokenizer;

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin/userboard")
    public String adminPageAllUserForm(Model model, HttpServletRequest request) {

        model.addAttribute("users", userService.findAllUsers());
        String accessToken = jwtTokenizer.getAccessTokenFromCookies(request);
        if (accessToken != null) {
            String username = jwtTokenizer.getUsernameFromToken(accessToken);
            User user = userService.findByUsername(username).orElse(null);
            model.addAttribute("user", user);
        }
        return "user/admin-all-user";
    }

또한 이미 configure 메서드에서 권한을 제한했지만 더욱 명확하게 하기위해 메서드 호출 전에 다시한번 확인차 

 @PreAuthorize("hasRole('ADMIN')")

어노테이션을 붙여주는 것이다.

  • @PreAuthorize("hasRole('ADMIN')")
    • 주로 메소드에서 사용
    • 특정 메소드에 접근할 수 있는 권한을 세밀하게 설정할 때 사용
    • 이 어노테이션은 메소드 호출 전에 현재 사용자의 권한을 확인하여, 지정된 역할(ADMIN)이 있는지 체크
    • 해당 역할이 없으면 메소드 호출이 거부

 

이렇게 권한을 제한했고 일반 사용자가 "/admin/**") url에 접근할 시 접근이 제한되게 된다. 이제 본격적으로 관리자 페이지를 구현해보겠다.

728x90

+ Recent posts