SpringBoot SpringSecurity 설정 v2-4. BasicAuthorizationFilter 설정

jeonbang123·2023년 4월 16일
0

springboot

목록 보기
13/14
  • SpringBoot SpringSecurity 설정 v2-1. securityConfig 설정-
  • SpringBoot SpringSecurity 설정 v2-2. UserDetails, UserDetailsService 설정
  • SpringBoot SpringSecurity 설정 v2-3. UsernamePasswordAuthenticationFilter 설정
  • SpringBoot SpringSecurity 설정 v2-4. BasicAuthorizationFilter 설정

1. UsernamePasswordAuthenticationFilter 설정

package com.codesign.base.jwt;


import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.codesign.base.auth.PrincipalDetails;
import com.codesign.base.model.User;
import com.codesign.base.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.ObjectUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


// 시큐리티가 fliter를 가지고 있는데 그 필터중에
// BasicAuthenticationFilter 라는 것이있음
// 해당 필터에서 무조건 토큰이 있는지 없는지를 검사한다.
@Slf4j
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {

    private UserService userService;

    public JwtAuthorizationFilter(AuthenticationManager authenticationManager, UserService userService) {
        super(authenticationManager);
        this.userService = userService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("토큰 여부 검사 필터");
        String authorization = request.getHeader(JwtProperties.HEADER_STRING);
        log.info("authorization : {}", authorization);
        if (ObjectUtils.isEmpty(authorization) || !authorization.startsWith("Bearer")) {
            chain.doFilter(request, response);
            return;
        }

        // jwt 토큰 검증을 해서 정상적인 사용자인지 확인
        String jwtToken = authorization.replace(JwtProperties.TOKEN_PREFIX, "");

        String username = JWT.require(Algorithm.HMAC512(JwtProperties.SECRET)).build().verify(jwtToken).getClaim("username").asString();
        log.info("username : {}", username);

        // 정상적으로 서명됨
        if (username != null) {
            User byUsername = userService.findByUsername(username);

            // JWT 토큰 서명을 통해서 서명이 정상이면 Authentication 객첵를 만들어준다.
            PrincipalDetails principalDetails = new PrincipalDetails(byUsername);
            Authentication authentication = new UsernamePasswordAuthenticationToken(principalDetails, null, principalDetails.getAuthorities());

            // 강제로 시큐리티의 세션에 접근하여 Authentication 객체를 저장
            SecurityContextHolder.getContext().setAuthentication(authentication);

            chain.doFilter(request, response);
        }
    }
}

1-1. doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)

  • 요청이 들어올때 토큰이 있는지 없는지 검사하는 필터
  • Header에 Authorization에 토큰을 꺼내서 유효한 토큰인지 검증
  • 유효한 토크이면 시큐리티 세션에 저장후 다음 필터 호출 (시큐리티세션에 저장하는 목적은 ROLE을 저장하기 위함)

2. JwtAuthorizationFilter 적용

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserService userService;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable(); // 위변조 방지 미사용
        http.cors().configurationSource(corsFilter()) // cors설정
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // session 미사용
                .and().formLogin().disable() // formlogin 미사용
                .httpBasic().disable() // Baerer 사용으로 Basic방식 미사용
                .addFilter(new JwtAuthenticationFilter(authenticationManager()))
                .addFilter(new JwtAuthorizationFilter(authenticationManager(), userService))
                .authorizeRequests()
                .antMatchers("/api/v1/user/**").permitAll()
                .antMatchers("/api/v1/manager/**").access("hasRole('ROLE_MANAGER')")
                .anyRequest().permitAll();
    }
    
    ...
    
}

.addFilter(new JwtAuthorizationFilter(authenticationManager(), userService)) 추가

  • authenticationManager()WebSecurityConfigurerAdapter에 정의 되어있음
  • userService는 해당 username의 유효성 확인을 위해

참고
https://www.youtube.com/watch?v=GEv_hw0VOxE&list=PL93mKxaRDidERCyMaobSLkvSPzYtIk0Ah

profile
Design Awesome Style Code

0개의 댓글