spring security실수

강찬우·2023년 12월 8일

jwt토큰을 이용한 로그인을 구현중에 발생한 실수이다.

분명 로그인시에 jwt토큰을 발급하고 postman을 이용해 유저가 서버에 정보를 요청할때 그 토큰을 같이 보냈다.
그런데 계속 Security context에서 유저에 대한 정보를 가져올 때 annonymousUser라고 뜨며 유저에 대한 정보를 받아오지 못했다.

java.util.NoSuchElementException: No value present

그래서 원인을 찾아보았다.

원인은 전에 테스트로 잠깐 쓰던 config파일이였다.

package com.ll.medium.global.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class ApiSecurityConfig {

    @Bean
    SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception{
        http
                .securityMatcher("/api/**","/**","http://localhost:5173")
                .csrf(
                        csrf-> csrf.disable()
                ).cors(
                        cors->cors.configure(http)
                );
        return http.build();
    }

}
package com.ll.medium.global.security;

import com.ll.medium.global.jwt.JwtAccessDeniedHandler;
import com.ll.medium.global.jwt.JwtAuthenticationEntryPoint;
import com.ll.medium.global.jwt.JwtFilter;
import com.ll.medium.global.jwt.TokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final TokenProvider tokenProvider;
    private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    private final JwtAccessDeniedHandler jwtAccessDeniedHandler;

    // PasswordEncoder는 BCryptPasswordEncoder를 사용
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }



    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                // token을 사용하는 방식이기 때문에 csrf를 disable합니다.
                .csrf(AbstractHttpConfigurer::disable)
                .sessionManagement(
                        sessionManagement ->
                                sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .exceptionHandling(exceptionHandling ->
                        exceptionHandling
                                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                                .accessDeniedHandler(jwtAccessDeniedHandler)
                )
                // enable h2-console
                .headers(headers ->
                        headers
                                .frameOptions(frameOptions ->
                                        frameOptions
                                                .sameOrigin()
                                )
                )
                .authorizeHttpRequests(request ->
                        request.requestMatchers("/api/authenticate","/api/member/join","/favicon.ico")
                                .permitAll()
                                .requestMatchers(PathRequest.toH2Console()).permitAll()
                                .anyRequest().authenticated()
                )
                .addFilterBefore(
                        new JwtFilter(tokenProvider),
                        UsernamePasswordAuthenticationFilter.class); // JwtFilter를 addFilterBefore로 등록했던 JwtSecurityConfig class 적용


        return httpSecurity.build();
    }

}

원래는 밑의 파일이 실행되면서 JwtFilter가 filterchain에 추가되어 토큰의 정보를 받은후에 올바른 토큰인지에 대한 확인후 유저정보를 받아줘야 하지만 전에 쓰던 위의 파일을 지우지 않아 밑의 파일이 적용되지 않았던것 같다.
이 실수를 코드의 흐름을 보다가 JwtFilter가 제대로 적용되지 않는다는 점을 찾아 실수를 찾을 수 있었다....

0개의 댓글