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
'Spring > Security' 카테고리의 다른 글
Spring : JWT 토큰 저장 DB 변경 (MySQL -> Redis) (0) | 2024.08.23 |
---|---|
JWT 로그인 시 Refresh-Token 저장소를 Redis로 변경 (0) | 2024.08.20 |
Spring Security + OAuth2 + JWT 를 사용한 로그인, 로그아웃 구현 - 3 (0) | 2024.08.13 |
Spring Security + OAuth2 + JWT 를 사용한 로그인, 로그아웃 구현 - 2 (0) | 2024.08.13 |
Spring Security + OAuth2 + JWT 를 사용한 로그인, 로그아웃 구현 - 1편 (0) | 2024.08.09 |