반응형
Spring Security
- 직접 구현하는 과정보다는 전체적인 플로우 개념에 대한 이해를 중점으로 진행한다.
- https://github.com/seongbinko/simple-order-app config 디렉토리에서 상세 내용은 확인 가능하다.
인증(Authentication)과 권한(Authorization)
- 인증: Id,Pw를 입력 받아 로그인 하는 과정 자체
- 권한: 보호된 리소스에 접근 가능한지를 결정하는 것을 의미
- 인가(Authorize): 권한을 부여하는 작업을 인가
Spring Security 구조
- UserDetailsService
- 실제 DB에서 사용자 인증정보를 가져오는 역할을 한다.
- UserDetails
- UserDeatils객체를 통해 권한 정보를 관리하기 때문에 UserDetails를 구현한 구현체가 반드시 필요하다
- CustomUserDetails를 만들고 Mebmer에 리턴해주는 방식을 채택하였다.
- 넘겨받은 정보를 통해 DB에서 찾은 사용자 정보
- UserDetails는 인증용객체(Member)와 도메인용 객체(CustomUserDetails)를 분리하지 않고 인증용 객체에서 상속해서 사용하기도 한다.
- GrantedAuthority
- UserDeatils객체를 통해 권한 정보를 관리하기 때문에 UserDetails를 구현한 구현체가 반드시 필요하다
- 동작 플로우
- Http Request : 사용자가 로그인 정보와 함께 인증을 요청한다.
- AuthenticationFilter가 요청을 가로 챈다. 가로친 정보를 바탕으로 UsernamePasswordAuthenticationToken 객체를 생성한다.
- AuthenticationFilter가 AuthenticationManger의 구현체인 ProviderManager에게 토큰 (UsernamePasswordAuthenticationToken)을 전달한다.
- 다시 AuthenticationProvider에 UsernamePasswordAuthenticationToken 객체를 전달합니다.
- AuthenticationProvider가 실제 데이터베이스에서 사용자 인증정보를 가져오는 UserDetailsService에 사용자 정보(아이디)를 넘겨줍니다.
- 넘겨받은 사용자 정보를 통해 DB에서 찾은 사용자 정보인 UserDetails 객체를 만듭니다.
- AuthenticationProvider(인증 제공자) 는 UserDetails를 넘겨받고 사용자 정보를 비교합니다.
- 인증이 완료되면 권한 등의 사용자 정보를 담은 Authentication 객체를 반환합니다. (인증 제공자 -> 인증 관리자)
- AuthenticationFilter에 Authentication 객체가 반환됩니다.
- Authentication 객체를 SecurityContext에 저장합니다.
Spring Security Filter (chaning 방식)
스프링 시큐리티는 필터체인을 통해 다양하게 커스트마이징이 가능하다
필터를 통해 인증과 인가를 하기 때문에 중요하다.
UsernamePasswordAuthenticationFilter를 주로 사용
- login 요청을 감시, 인증 과정을 진행
- spring security configure를 보면 기존의 필터전에 커스텀한 Jwt필터가 동작하고 UsernamePasswordAuthenticationFilter로 전달하는 역할을 한다.
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
JWT
- Json 객체를 통해 안전하게 정보를 전송할 수 있는 토큰이다.
- JWT는 '.' 구분자로 Header(토큰타입,알고리즘방식).payload(실제전달정보).signature(위변조방지값)
구현 (관련 된 곳 숫자를 작성해봄)
https://github.com/seongbinko/simple-order-app config 디렉토리에서 상세 내용은 확인 가능하다.
WebSecurityConfig extends WebSecurityConfigurerAdapter
- @EnableWebSecurity
JwtTokenProvider.class
토큰 생성[10]: public String createToken(String nickname, String role) { Claims claims = Jwts.claims().setSubject(nickname); claims.put("role", role); Date now = new Date(); return Jwts.builder() .setHeaderParam("typ", "JWT") .setClaims(claims) // 데이터 .setIssuedAt(now) // 토큰 발행일자 .setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time .signWith(SignatureAlgorithm.HS256, secretKey) // 암호화 알고리즘, secret값 세팅 .compact(); // String type으로 return }
토큰 인증 정보 조회[6] public Authentication getAuthentication(String token) { UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPk(token)); return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); }
JwtAuthenticationFilter.class
[8][9][10]의 과정으로 [11] SecurityContextHolder에 Authentication 객체를 저장한다.
- Filter 기능을 사용하여 시큐리티를 동작시키는데 GenericFilterBean은 Filter기능을 사용하면서 Spring config설정 정보를 쉽게 처리하기 위한 GenericFilterBean을 제공한다.
- GenericBean을 통해 스프링 컨테이너에 올라간 bean(jwtTokenProvider)를 사용할 수 있다.
- Filter는 servlet기 때문에 servlet의 ServletContext에 spring의 ApplicationContext를 연동해야 한다
참조
- https://webfirewood.tistory.com/115
- https://minkukjo.github.io/framework/2020/12/18/Spring-142/
- OncePerRequestFilter와 Filter(GenericBean)의 차이
'프로그래밍 > 스프링 자바' 카테고리의 다른 글
[Java] Java enum 활용 (0) | 2022.07.17 |
---|---|
[JPA] N+1 문제 개념, 원인, 해결방안 (0) | 2021.07.13 |
TDD 방식으로 개발 예제 (Junit5) (0) | 2021.07.04 |
[Java] JVM, 자바 메모리, GC (0) | 2021.07.03 |
[Spring] 스프링 개념 정리 (0) | 2021.06.30 |