인증이나 권한이 필요한 요청
356
작성한 질문수 9
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("인증이나 권한이 필요한 요청");
String jwtHeader = request.getHeader(JwtProperties.HEADER_STRING);
if(jwtHeader ==null || !jwtHeader.startsWith(JwtProperties.TOKEN_PREFIX)) {
/**
* 이거 필터로 걸려야 되는거 아니야?! 인증이나 권한이 없는거니깐
*/
chain.doFilter(request, response);
return;
}
System.out.println("jwtHeader:" + jwtHeader);
String token = request.getHeader(JwtProperties.HEADER_STRING).replace(JwtProperties.TOKEN_PREFIX, "");
String username = JWT.require(Algorithm.HMAC512(JwtProperties.SECRET)).build().verify(token)
.getClaim("username").asString();
if(username !=null) {
User user = userRepository.findByUsername(username);
// 인증은 토큰 검증시 끝.
// 인증을 하기 위해서가 아닌 스프링 시큐리티가 수행해주는 권한 처리를 위해
// 아래와 같이 토큰을 만들어서 Authentication 객체를 강제로 만들고 그걸 세션에 저장!
PrincipalDetails principalDetails = new PrincipalDetails(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(
principalDetails, // 나중에 컨트롤러에서 DI해서 쓸 때 사용하기 편함.
null, // 패스워드는 모르니까 null 처리, 어차피 지금 인증하는게 아니니까!!
principalDetails.getAuthorities());
// 강제로 시큐리티의 세션에 접근하여 값 저장
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
만약 "localhost:8080/home"으로 uri를 요청한다면 SecurityConfig에 해당 uri는 모두 허용이기 때문에 해당 스프링 시큐리티 필터를 타면 안되는것이 아닙니까??
그리고 탄다고 해서 인증권한이 요구되는 uri에서 해당 필터가 타게된다면 JWT토큰이 없으면 해당 인증이 안된다고 판단하여 다음 필터를 타지않고 reject를 해야하는것이 아닙니까? (if(jwtHeader==null ~ 부분에서))
그리고 마지막으로 궁금한점이 JWT 토큰을 가지고 인증 uri를 호출하면 사용자권한을 스프링 시큐리티를 통해서 편리하게 사용하기 위해서 강제로 Authentication객체를 생성하는데 해당 로직으로 한다면 JWT토큰이 올때마다 JWT토큰이 유효하다면 JWT토큰에서 username을 가지고 오는데 그럼 한 사용자가 인증이 필요한 uri로 올때마다 계속 Attentication객체를 생성해서 스프링 시큐리티에 저장하는것이 아닙니까?
읽어주셔서 감사합니당.!!
답변 3
0
우선 하나씩 하시죠 !!
JWT의 이점인 세션영역을 사용하지 않는다는 장점!!
이 부분 부터!!
JWT를 사용하는 이점이 세션영역을 사용하지 않는다는 것은 아닙니다.
세션영역 자체가 나쁜 저장소가 아니기 때문입니다.
우선 세션영역을 사용하지 않으려는 이유는 서버의 수평적 확장이 있을 때
세션 영역이 서버마다 생기기 때문에 .... 생기는 문제를 없애기 위해 세션영역을 안쓰려는 것입니다.
그런데 JWT를 사용하면서 서버가 확장되어도 인증이 가능해지고
잠깐 필요한 데이터만 세션영역에 저장해두고 쓰고 버리는 식으로 가면 좋은 점만 가져갈 수 있습니다.
우선 이부분 부터 명확히 생각해보세요
0
1. 인증이 필요한 uri요청이 올때마다 세션을 생성한다면 JWT의 이점인 세션영역을 사용하지 않는다는 장점이 없어지는것이 아닙니까? 단지 스프링 시큐리티를 통해서 권한체크를 편리하게 하기 위해서 세션영역을 계속 할당하고 생성하면 좋지 않은 방법이지 않습니까?!
2.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //세션을 사용하지 않겠다!
.and()
.formLogin().disable()
.httpBasic().disable() //Bearer 방식 사용 -> header 에 authentication 에 토큰을 넣어 전달하는 방식
.apply(new MyCustomDsl())
.and()
.authorizeRequests(authroize -> authroize
.antMatchers("/api/v1/user/**")
.hasAuthority("USER")
.antMatchers("/api/v1/manager/**")
.hasAuthority("MANAGER")
.antMatchers("/api/v1/admin/**")
.hasAuthority("ADMIN")
.anyRequest().permitAll())
.build();
}
.anyRequest().permiAll()로 인해서 위의 uri이 아닌 상황에서는 인증 권한체크를 하지 않는것이 아닙니까?
3.
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("인증이나 권한이 필요한 요청");
String jwtHeader = request.getHeader(JwtProperties.HEADER_STRING);
if(jwtHeader ==null || !jwtHeader.startsWith(JwtProperties.TOKEN_PREFIX)) {
/**
* 이거 필터로 걸려야 되는거 아니야?! 인증이나 권한이 없는거니깐
*/
chain.doFilter(request, response);
return;
}
System.out.println("jwtHeader:" + jwtHeader);
String token = request.getHeader(JwtProperties.HEADER_STRING).replace(JwtProperties.TOKEN_PREFIX, "");
String username = JWT.require(Algorithm.HMAC512(JwtProperties.SECRET)).build().verify(token)
.getClaim("username").asString();
if(username !=null) {
User user = userRepository.findByUsername(username);
// 인증은 토큰 검증시 끝.
// 인증을 하기 위해서가 아닌 스프링 시큐리티가 수행해주는 권한 처리를 위해
// 아래와 같이 토큰을 만들어서 Authentication 객체를 강제로 만들고 그걸 세션에 저장!
PrincipalDetails principalDetails = new PrincipalDetails(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(
principalDetails, // 나중에 컨트롤러에서 DI해서 쓸 때 사용하기 편함.
null, // 패스워드는 모르니까 null 처리, 어차피 지금 인증하는게 아니니까!!
principalDetails.getAuthorities());
// 강제로 시큐리티의 세션에 접근하여 값 저장
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
주석으로 표시해둔 부분에서 JWT토큰을 가지고 있는 사용자가 요청한 상황이니 필터를 통해서 컨트롤러등까지 호출하지 않게 처리해야되지 않습니까? doFilter를 호출하지 않고
답변해주셔서 진심으로 감사드립니당!!
0
그리고 마지막으로 궁금한점이 JWT 토큰을 가지고 인증 uri를 호출하면 사용자권한을 스프링 시큐리티를 통해서 편리하게 사용하기 위해서 강제로 Authentication객체를 생성하는데 해당 로직으로 한다면 JWT토큰이 올때마다 JWT토큰이 유효하다면 JWT토큰에서 username을 가지고 오는데 그럼 한 사용자가 인증이 필요한 uri로 올때마다 계속 Attentication객체를 생성해서 스프링 시큐리티에 저장하는것이 아닙니까?
맞아요!! 요청할 때마다 세션에 보관합니다.
만약 "localhost:8080/home"으로 uri를 요청한다면 SecurityConfig에 해당 uri는 모두 허용이기 때문에 해당 스프링 시큐리티 필터를 타면 안되는것이 아닙니까??
이 부분은 코드를 봐야 알 것 같아요. 본인 코드를 github에 올리고 어느 파일을 봐야하는지 알려주세요.
그리고 탄다고 해서 인증권한이 요구되는 uri에서 해당 필터가 타게된다면 JWT토큰이 없으면 해당 인증이 안된다고 판단하여 다음 필터를 타지않고 reject를 해야하는것이 아닙니까? (if(jwtHeader==null ~ 부분에서))
위 답변과 동일합니다.
JWT를 구현한 다음 이 API를 호출해서 사용하는 것은 프론트엔드 쪽에서 하는 역할인가요?
0
96
1
Jwt쓰면 스프링시큐리티는 필수적으로 사용해야하나요?
0
401
1
13:23 system.out 출력문이 다르게 나옵니다.
0
130
1
수료증 문의
0
227
2
9분대에 질문이 있습니다 !
0
114
1
password 비교를 하지 않았는데 어떻게 인증이 통과된 건가요?
0
321
1
이전 강의 참고하라는 말씀
0
253
1
강의 실습하다가 막히는 분들 참고(2024년8월 기준)
2
1116
2
구글 소셜 로그인 302
0
200
1
오류 문의 _ org.springframework.orm.jpa.JpaSystemException: could not deserialize
1
584
1
[자바] 시큐리티 Config 참고
13
953
1
이론강의
0
280
1
SpringSecurity JWT 로그인 URL 2개 설정하는 방법
0
487
1
2024.06기준) 최근 SecurityConfig 설정 문의
0
922
3
구글 로그인시 authentication이 null 값이라고 에러가 발생합니다.
0
678
2
특정 url필터 거는 방법 이슈
0
422
1
강사님께서 말씀하시는 시큐리티세션이 SecurityContext인가요?
0
278
1
25강 마지막 테스트에서 오류
1
1044
2
jwt를 저장하는 위치에 궁금한 점이 있습니다.
0
298
1
mustache를 사용하지 않고 thymeleaf를 사용하려고 하는데
0
697
1
세션 인증방식이 REST 원칙에 위배되는 건가요?
0
340
1
jwt와 실제데이터의 관계
1
244
1
jwt 와 세션ID의 관계
1
313
1
SecurityConfig에서 세션 설정, 인가 설정
0
421
1





