JAVA

Principal null 이슈 해결 (feat. WebSecurityConfig.java)

기록해연 2025. 5. 14. 11:11

 

java.lang.NullPointerException: Cannot invoke "java.security.Principal.getName()" because "principal" is null 
at com.side_fpt.team_service.controller.VoteController.submitVote(VoteController.java:58)

 

요즘 팀원들과 사이드 프로젝트를 하고 있는데, 분명 로그인 되어있는데 Principal 정보를 못받아오는 것.

로그 확인해보니 principal이 null이라 getName()이 불가해서 나는 오류로 확인됨.

 

package com.side_fpt.team_service.security;

import com.side_fpt.team_service.util.constant.Privillages;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;


@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig {

    private static final String[] WHITELIST = {
            "/login",
            "/register",
            "/css/**",
            "/fonts/**",
            "/js/**",
            "**",
            "/check-email",
            "/forgot-password",
            "/reset-password",
            "/change-password"
    };

    @Bean
    public static PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers(WHITELIST).permitAll()
                        .requestMatchers("/admin/**").hasAnyRole("ADMIN", "EDITOR")
                        .requestMatchers("/admin/**").hasAuthority(Privillages.ACCESS_ADMIN_PANEL.getPrivillage())         // admin 페이지는 특정권한만 접근가능.
                        .anyRequest().authenticated()

                )
                
   // 이하 생략

 

WHITELIST로 설정란 루트 중에 "**" 전체소스를 표현하는 스트링이 들어가 있었다.

문제가 되는 Principal == null 이슈는 SecurityFilterChain 설정에서 너무 많은 경로를 permitAll()로 허용해서 인증 정보가 붙지 않기 때문으로 판단되어, 해당 "**"를 제거 후 실행하니 정상적으로 principal 정보가 들어오는 것으로 확인되었다.

 

💡  .permitAll() :

해당 요청 경로에 대해 Spring Security의 인증 필터를 통과시켜 로그인 없이도 접근 가능하게 해 줌.

 

💡  추가 정보

 

메서드 설명
.permitAll() 인증 없이 접근 허용
.authenticated() 인증된 사용자만 접근 허용
.hasRole("USER") 특정 역할을 가진 사용자만 접근 허용
.denyAll() 모든 사용자 접근 거부