SpringSecurity - JWT 토큰 생성

hsso_o·2024년 7월 25일
0

스터디

목록 보기
32/44

어제 jwt 하려고 세팅까지 해놨다가 오늘 토큰 발급까지 완료했다.

SecurityConfig에서 달라진 게 있다면,,
1. http.addFilter()로 필터 적용해주기
2. 세션을 사용하지 않으므로 .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))로 stateless 서버로 설정해주기
3. 기본 폼 로그인 비활성화
4. http 기본 인증 비활성화

http.addFilter()

Corsfilter

  • CORS(Cross-Origin Resource Sharing)를 처리하기 위한 필터
    • CORS
      • 기본적으로 웹 브라우저는 보안상의 이유로 다른 도메인 간의 요청을 제한
      • 한 도메인에서 로드된 웹 페이지가 다른 도메인의 리소스에 접근할 수 있도록 허용하는 메커니즘
@Bean
    public CorsFilter corsFilter(){

        // 특정 URL 패턴에 대한 CORS 설정을 등록하기 위한 소스
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        CorsConfiguration config = new CorsConfiguration();  // CORS 정책을 정의하는 객체
        config.setAllowCredentials(true);  // 클라이언트 측에서 자바스크립트를 통해 응답을 처리할 수 있도록 설정
        config.addAllowedOrigin("*");      // 모든 ip에 응답 허용
        config.addAllowedHeader("*");      // 모든 header에 응답 허용
        config.addAllowedMethod("*");      // 모든 post, get, put, delete, patch 요청 허용

        // 특정 URL 패턴(/api/**)에 대해 위에서 정의한 CORS 설정을 등록
        source.registerCorsConfiguration("/api/**", config);
        // 새로운 CorsFilter 객체를 생성하고 반환 -> 해당 필터는 스프링 시큐리티 필터 체인에 추가되어 CORS 규칙을 적용
        return new CorsFilter(source);
    }

JwtAuthenticationFilter

  • 로그인 요청을 처리하고, 사용자가 올바르게 인증되었는지 확인한 후 JWT 토큰을 생성하여 응답 헤더에 추가
// 스프링 시큐리티에서 UsernamePasswordAuthenticationFilter 존재
// /login 요청해서 username, password 전송하면(post)
// UsernamePasswordAuthenticationFilter 동작함
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;
    private final JwtUtil jwtUtil;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtUtil jwtUtil) {
        this.authenticationManager = authenticationManager;
        this.jwtUtil = jwtUtil;
    }

    // /login 요청을 하면 로그인 시도를 위해서 실행되는 함수
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        System.out.println("JwtAuthenticationFilter 로그인 시도 중");

        // 1. username, pw 받아서
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            User user = objectMapper.readValue(request.getInputStream(), User.class);

            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());

            // 정상인지 로그인 시도. AuthenticationManager로 로그인(인증) 시도
            // PrincipalDetailsService의 loadUserByUsername() 함수가 실행된 후, 정상이면 authentication이 리턴됨
            Authentication authentication = authenticationManager.authenticate(token);

            // 로그인이 정상적으로 되면  PrincipalDetails 객체를 얻음
            PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
            System.out.println("로그인 완료됨 : " + principalDetails.getUser());

            // authentication 객체가 session영역에 저장을 해야하고 그 방법이 return 해주면 됨
            // 리턴의 이유는 권한 관리를 security가 대신 해주기 때문에 편하려고 하는거임
            // 굳이 JWT 토큰을 사용하면서 세션을 만들 이유가 없음. 근데 단지 권한 처리 때문에 session 넣어줌
            return authentication;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // attemptAuthentication 실행 후 인증이 정상적으로 되었으면 실행
    // JWT 토큰을 만들어서 request 요청한 사용자에게 JWT 토큰을 response 해주면 됨
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain chain, Authentication authentication) throws IOException, ServletException {

        System.out.println("successfulAuthentication 실행 -> 인증 완료");
        // 인증된 사용자 정보를 PrincipalDetails 객체에서 가져옴
        PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();

        // JWT 토큰 생성
        String jwtToken = jwtUtil.createToken(principalDetails.getUser().getUsername());

        // 응답 헤더에 생성된 JWT 토큰을 추가
        response.addHeader("Authorization", "Bearer " + jwtToken);
    }
}

이렇게 추가해주면
저런 식으로 헤더에 Authorization이 새롭게 추가된 걸 볼 수 있다..!.!
테스트라 그냥 아무 키나 넣고 생성함ㅎㅎ

profile
아뇨 소혠데요-

0개의 댓글