• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

로그인 요청시 401 상태 반환

23.06.21 02:08 작성 23.06.21 02:18 수정 조회수 693

0

로그인 시도 시 401 오류를 반환하고 있습니다.

user-service의 AuthenticationFilter 에서 인증이 실패가 된지 알아 디버깅을 해보니 인증이 성공해서 도대체 어디가 문제인지 알 수가 없습니다.

그래서 유저 서비스에 직접 접근을 할 시 똑같은 401 오류를 반환하고 있습니다.

그리고 유저 서비스에 직접 접근을 하거나 게이트웨이로 접근해도 성공에 관한 메소드는 작동하지 않습니다.

< 스프링 부트, 시큐리티는 현재 최신 버전입니다. >

 

AuthenticationFilter 클래스

@RequiredArgsConstructor
@Slf4j
public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private final UserService userService;
    @Value("${token.expiration_time}")
    private Long EXPIRATION_TIME;
    @Value("${token.secret}")
    private String secretKey;
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        log.info("attemptAuthentication");
        try{
            RequestLoginVo cred=new ObjectMapper().readValue(request.getInputStream(), RequestLoginVo.class);
            log.info(cred.getEmail()+" "+cred.getPassword());
            return this.getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(
                    cred.getEmail(),
                    cred.getPassword(),
                    new ArrayList<>()
            ));
        } catch(IOException e){
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {

        String userName = ((User)authResult.getPrincipal()).getUsername();
        UserDto userDto =  userService.getUserDetailByEmail(userName);

        String token = Jwts.builder()
                .setSubject(userDto.getUserId())
                .setExpiration(new Date(System.currentTimeMillis() +
                        EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS512, secretKey)
                .compact();


        response.addHeader("token",token);
        response.addHeader("userId",userDto.getUserId());
    }
}

loadUserByUsername 메소드

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("loadUserByUsername "+username);
 Optional<UserEntity> userEntity = userRepository.findByEmail(username);
 log.info(userEntity.get().getEmail()+" "+userEntity.get().getName()+" "+userEntity.get().getEncryptedPwd());
 if(userEntity.isEmpty()){
throw new UsernameNotFoundException("해당 유저는 존재하지 않습니다.");

 }
return new User(userEntity.get().getEmail(), userEntity.get().getEncryptedPwd(), true, true, true, true,
 new ArrayList<>());
}

WebSecurity 클래스

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurity{

    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final UserService userService;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
               .csrf(csrf -> csrf.disable())
                .headers(headers ->
                        headers
                                .frameOptions((frameOptions) -> frameOptions.disable()))
               .authorizeRequests(authorize -> authorize
                               .requestMatchers(PathRequest.toH2Console()).permitAll()
                               .requestMatchers("/**").hasIpAddress("127.0.0.1")
                      )
               .addFilter(getAuthenticationFilter());


       return http.build();

    }

    @Bean
    public AuthenticationManager authenticationManager() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userService);
        provider.setPasswordEncoder(bCryptPasswordEncoder);
        return new ProviderManager(provider);
    }

    private AuthenticationFilter getAuthenticationFilter() {
        AuthenticationFilter authenticationFilter = new AuthenticationFilter(userService);
        authenticationFilter.setAuthenticationManager(authenticationManager());
        return authenticationFilter;
    }


}

ApiGateWay - Application.yml 유저 서비스 부분

      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/login
            - Method=POST
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>.*), /$\{segment}
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/users
            - Method=POST
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>.*), /$\{segment}
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/**
            - Method=GET
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>.*) , /$\{segment}
            - AuthorizationHeaderFilter

답변 1

답변을 작성해보세요.

-1

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.06.23

안녕하세요, 인프런 AI 인턴입니다.

401 오류는 해당 사용자에게 인증 오류가 발생했음을 알리는 오류 코드입니다. 그리고 보통 인증 오류는 로그인 정보가 유효하지 않거나 인증 토큰이 잘못된 경우 발생합니다.

로그인 정보가 맞는데도 오류가 발생한다는 것은 다른 문제가 있을 수 있습니다. 이를 해결하기 위해서는 에러 로그에 더 자세한 정보가 필요합니다.

로그인 요청을 할 때 어디에서 오류가 발생하는지, 그리고 유저 서비스에 직접 접근해도 같은 문제가 발생한다면, 해당 서비스에서 문제가 발생 중인 것 같습니다.

추가적으로, 해당 문제를 해결하려면 보안 관련 설정을 확인해보는 것이 좋습니다. 시큐리티 설정이나 인증 관련 설정 중 누락된 부분이 있는지 확인해보세요.

이 부분들을 더 자세히 파악하셔서 구체적으로 문제 인식을 해보시길 권장드리며, 문제를 해결하지 못하면 해당 서비스나 프레임워크의 커뮤니티나 지식공유자에게 문의하여 도움을 받으시길 바랍니다.

도움이 되었길 바라며, 성공적인 문제 해결을 기원합니다. 감사합니다.