스크럼
- 스프링 시큐리티 + JWT 트러블 슈팅
- controller에서 V1 패키지 유무
트러블 슈팅 목록
토큰은 생성되지만, 보관을 해야함(쿠키,헤더,등등)
- 컨트롤러단에 ResponseServlet에 쿠키에 JWT 저장으로 진행
requestMatchers.permitAll();을 했지만 jwt 생성이 되지 않아 예외를 발생하는 문제.
- &와 && 차이 였다.
- & 는 앞의 조건식이 false 여도 뒤의 조건식이 true인지 false 인지 판별한다. 어차피 결과는 false인데도 말이다.
- && 는 앞의 조건식이 false 라면, 뒤의 조건식은 true인지 false인지 신경쓰지 않는다. 어차피 결과는 false이기 때문이다.
Security 버전문제에 따른 메서드 변경필요. (SecurityConfig.Class)
- 변경 전
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests()
// 로그인
.requestMatchers("/api/signIn").permitAll()
// 회원 가입
.requestMatchers("/api/signUp").permitAll()
.requestMatchers("/api/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class)
.build();
}
- 변경 후
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.httpBasic(HttpBasicConfigurer::disable)
.csrf(CsrfConfigurer::disable)
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authorize ->
authorize
.requestMatchers("/api/signin", "/api/signup").permitAll()
.requestMatchers("/api/v1/admin").hasRole("ADMIN")
.anyRequest().authenticated())
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
Refresh Token RDBMS와 NOSQL 차이
- RDBMS는 클라이언트에 Access, Refresh 저장, 서버에 Refresh 저장하여 클라이언트의 Refresh를 가져와서 확인
- NoSQL는 Key, Value 형식이라 클라이언트에 Access만 저장해도 됨 서버에 “Access”:”Refresh”로 가져와서 확인
- 데이터베이스 저장 방식의 차이로 프로세스가 다르다.
REST 응답을 받을 때 오류가 나면 trace 내용이 노출 되는 문제
서버에서 톰캣 설정을 수정 하거나, Exception을 따로 만들어서 반환
server:
port: 8080
error:
include-stacktrace: never
스프링 시큐리티 비밀번호 조회시 단방향 인코딩을 안해도 바로 인코딩 및 검사가 되는 이유
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return userRepository.findByEmail(email)
.map(user -> org.springframework.security.core.userdetails.User.builder()
.username(user.getEmail())
.password(user.getPassword())
.roles(user.getAuthorities().toString())
.build())
.orElseThrow(() -> new UsernameNotFoundException("회원을 찾을 수 없습니다."));
}
UserService에서 비밀번호 검증 없이 이메일로만 찾아서 사용자 정보를 반환하는 것을 보고, 비밀번호 없이 이메일로만 되는 건지 궁금해서 비밀번호를 틀리게 하여 테스트를 진행했을 때 403 Error가 발생한 것을 확인 할 수 있었다.
가능한 이유는 AuthenticationManager.authenticate(Authentication)에서 authenticate 메소드가 체크를 해준다.
- 시큐리티에 내장된 AuthenticationProvider의 authenticate() 메서드 호출
- DaoAuthenticationProvider.additionalAuthenticationChekcs(UserDetails, UsernamePasswordAuthenticationToken) 메서드 실행
- 아래가 additionalAuthenticationChekcs 메소드
String presentedPassword = authentication.getCredentials().toString();
if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
logger.debug("Authentication failed: password does not match stored value");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials"));
}
기술면접 Overloading, Overriding 차이
- Overloading: 같은 메소드 명에 매개변수가 다른 것
- Overriding: 같은 메소드 명에 매개변수가 같은 것, 재정의 하는 것
'항해99' 카테고리의 다른 글
항해99 실전 프로젝트 (8일차) (0) | 2024.02.03 |
---|---|
항해99 기술면접 (1) | 2024.02.03 |
항해99 실전 프로젝트 (6일차) (0) | 2024.02.01 |
항해99 실전 프로젝트 (5일차) (0) | 2024.01.31 |
항해99 실전 프로젝트 (4일차) (0) | 2024.01.30 |