JAN's History
JWT를 구현할 때 권한관리를 하기 위해 Authentication을 return 해야하는 이유 본문
JWT를 공부하던 도중 Authentication 객체를 반환하는 이유가 권한 관리를 위해서라는 말이 이해가 가지 않아 정리해보기로 결심!
일단 저의 코드 구조를 대략적으로 적어보겠습니다.
User
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String username;
private String password;
private String roles; //USER, ADMIN
//하나의 유저당 role이 2개 이상일 경우를 대비해서!
public List<String> getRoleList(){
if(this.roles.length() > 0){
return Arrays.asList(this.roles.split(","));
}
return new ArrayList<>();
}
➡️roles가 있으므로, 권한이 필요함!
Security Config
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
- configure(HttpSecurity http): HTTP 요청에 대한 인가 설정을 구성합니다. 예를 들어, "/admin/**" 경로는 ADMIN 역할을 가진 사용자만 접근할 수 있도록 설정합니다.
- configure(AuthenticationManagerBuilder auth): 사용자 인증을 설정합니다. userDetailsService를 통해 사용자 정보를 조회하고, passwordEncoder()를 통해 비밀번호를 암호화하여 인증을 수행합니다.
Controller
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/public")
public String publicEndpoint() {
return "Public endpoint accessed";
}
@GetMapping("/admin")
public String adminEndpoint() {
return "Admin endpoint accessed";
}
@GetMapping("/user")
public String userEndpoint() {
return "User endpoint accessed";
}
}
➡️/public은 모든 사용자에게 허용되고, /admin은 ADMIN 권한을 가진 사용자에게만 허용됩니다. /user는 인증된 모든 사용자에게 허용됩니다.
동작 방식 요약
- 사용자가 로그인을 하면 PrincipalDetailsService에서 사용자 정보와 권한을 조회해 UserDetails 객체를 생성합니다
- Spring Security는 UserDetails 객체를 Authentication 객체에 저장해 Security Context에 저장합니다.
- HTTP 요청이 들어올 때마다, Authentication 객체를 통해 사용자 권한을 확인하고 접근 제어를 수행합니다 !
Authentication 객체를 통해 사용자 권한을 확인하는 과정
1. 사용자 로그인
- 사용자가 아이디와 비밀번호로 로그인을 수행합니다.
- Spring Security는 UsernamePasswordAuthenticationToken을 생성해 사용자의 아이디와 비밀번호를 포함시킨 후 AuthenticationManager를 통해 인증을 시도합니다.
- AuthenticationManager는 AuthenticationProvider를 사용해 실제 인증을 수행하고, 성공하면 Authentication 객체를 반환합니다.
2. HTTP 요청 처리
- 사용자가 로그인 후, 다시 HTTP 요청을 보냅니다.
- 예를 들어 'api/admin' 엔드 포인트에 접근하는 것처럼!
- Spring Security는 SecurityContext에서 현재 사용자의 Authentication 객체를 가져옵니다.
- 해당 Authentication 객체를 통해 사용자의 권한을 확인합니다
- 예를 들어 hasRole("Admin")을 통해!
- 사용자가 권한을 가지고 있으면 요청을 허용하고 그렇지 않으면 접근을 거부합니다.
'JWT' 카테고리의 다른 글
[최종] JWT 구현하기 : 생성하고 인증하기 (0) | 2024.07.13 |
---|---|
JWT 구현하기 : 로그인 요청 시 JWT 응답(Response) (0) | 2024.07.10 |
JWT 임시 토큰으로 필터 테스트 (0) | 2024.07.06 |
JWT를 구현하기전, Filter 등록 테스트 (0) | 2024.07.04 |
JWT를 구현하기전, 인증/인가 동작 원리: FilterChain을 이해해보자! (0) | 2024.07.03 |