묻고 답해요
137만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
섹션 13의 5번째 강의(CustomUserDetails 구현하기) 질문입니다. !!
SecurityConfig 클래스에서 @Bean 으로 등록한 UserDetailsService 클래스는 http.userDetailsService(userDetailsService) 이런식으로 설정하지 않는데, 그 이유를 알 수 있을까요 ?? 커스텀하게 만든 UserDetailsService 즉, FormUserDetailsService 를 사용하기 위해서는 http.userDetailsService(userDetailsService) 이런식으로 설정을 해야된다고 강의에 설명되어 있었습니다. 근데, SecurityConfig 클래스에서 @Bean 으로 등록한 UserDetailsService 클래스도 걀국 우리가 직접 커스텀하게 만든것이지 않나요..? 그러면 이클래스도 http.userDetailsService(userDetailsService) 이런식으로 설정을 해야할거 같은데 안해도 정상적으로 작동하는 이유가 궁금합니다 !!
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
FormLogin, HttpBasic를 모두 비활성화해도 로그인 이후에 Redirect가 발생하나요?
안녕하세요. 강사님. 강의 외적인 내용이지만, 질문 좀 드리겠습니다.JWT로 로그인하는 스프링 서버를 만들었는데요.클라우드에 올린 서버가 포스트맨의 POST 형식의 로그인 요청을 수행한 뒤, 동일한 url의 GET 요청으로 Redirect 되는 현상을 발견했습니다.스프링 서버를 로컬에서 띄우는 경우에는 발생하지 않습니다. 강의를 전부 듣지는 않았지만, FormLogin, HttpBasic를 모두 비활성화해도 로그인 이후에 Redirect가 발생하나요? Redirect를 안하고 싶은 경우는, 어떻게 설정하면 될까요?JwtFilter의 doFilter 로직에 AuthenticationSuccessHandler 구현체를 만들어서 처리하면 되는 것까지 확인했습니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
섹션 5의 세션 고정 보호 강의 질문
섹션 5의 세션 고정 보호 강의 실습 부분을 보면, 루트경로(/) 로 요청했을때도 응답에 세션아이디가 저장된 쿠기가 날라왔습니다.즉, 세션 생성 정책이 디폴트(ifRequired ) 인데 서버에 세션이 생성된 것인데, 혹시 세션이 어느부분에서 생성되었는지 알수 있을까요..?? ++ 추가)) 섹션 5의 SessionManagementFilter / ConcurrentSessionFilter - 2 강의를 보니 .maximumSessions() 설정을 해야만 세션관련 작업을 하는 필터들이 정상적으로 등록된다고 설명돼있는데 위의 실습은 이 설정을 하지 않아서 필터들이 등록되지 않은 걸까요..??근데 세션 고정 보호 적용은 어떻게 적용된건지 모르겠네요..ㅠㅠ
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
FilterChain 내 일반 서블릿 필터와 DelegatingFilterproxy의 차이점
안녕하세요, 좋은 강의에 항상 감사드리고 있습니다. 다름이 아니고 수업자료 내 FilterChain 그림에 보면, 그냥 Filter와 DelegatingFilterProxy 가 연결되어 있으며, DelegatingFilterProxy 가 FilterChainProxy에 보안처리를 위임하고 있습니다.한편, 코드 내에서 디버깅을 하면서 확인할 수 있는 필터는 모두 FilterChainProxy 안에 있는 필터들(강의영상에서는 16개)만 확인이 되고, DelegatingFilterProxy가 아닌 보통 서블릿 필터는 확인이 되지 않는 것 같습니다.DelegatingFilterProxy가 Spring에서 Filter을 사용할 수 있도록 하는 역할을 한다고 말씀하신 것으로 보아 다른 Filter 들은 Spring 코드 내에서 어떤 역할(Authentication인지 등..)을 하는 지 확인할 수 없는 것인지요?또한 코드 내에서 확인이 안된다면 Tomcat 등 WAS 자체의 스펙 내에서 확인이 되는 건가요? 감사합니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
InMemoryUser 방식으로 사용자 인증 확인중
코드상에서 사용자를 여러명 생성해서 인증 테스트 중입니다. application.yml 파일에 user 1명 생성해서 할 때는 정상적으로 잘 동작하는데요SecurityConfig 파일에 사용자를 코드로 생성해서 구동하면 정상적으로 실행되지 않습니다.코드를 따라했음에도 불구하고 스프링 구동 로그에 패스워드가 뜨는걸 보면 해당 설정이 제대로 동작되지 않는것 같습니다. 스프링 부트 버전 3.2.5 package com.example.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @EnableWebSecurity @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .formLogin(Customizer.withDefaults()); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withUsername("user").password("{noop}1111").roles("USER").build(); UserDetails user2 = User.withUsername("user2").password("{noop}1111").roles("USER").build(); UserDetails user3 = User.withUsername("user3").password("{noop}1111").roles("USER").build(); return new InMemoryUserDetailsManager(user, user2, user3); } } 실행 코드 입니다. application.yml 파일과 동시에 실행하면 application.yml 파일의 사용자로 동작하며application.yml의 정보를 삭제하고 실행하면 구동 로그에 패스워드가 뜨면서 위의 사용자 정보로 동작하지 않습니다. 어떤 부분을 확인해 봐야 할까요? 스프링 부트 버전 차이일 까요?
-
해결됨스프링 시큐리티 완전 정복 [6.x 개정판]
스프링 시큐리티의 필터를 동적으로 적용할 수 있나요?
안녕하세요. 아직 강의를 듣는 초반입니다. 미리 기능의 가능 여부가 궁금하여 여쭤봅니다.클라이언트의 요청을 필터의 설정에 따라 인증/인가 등을 판단하는데요.필터에 설정하는 값들을 DB 또는 파일 등에 넣어 놓고 실시간으로 동적으로 요청이 올때의값을 읽어와서 필터링 하는것도 혹시 가능할지 궁금하여 여쭤봅니다.설정이 초기에만 로드되어 계속 사용 되는 것인지 아니면 매 요청시에 설정을 확인하여 적용하는 것인지매 요청시에 설정을 확인하면 해당 요청시에 값을 동적으로 읽어 와서 적용시킬 수 있지 않을까 싶은 생각에서가능한지 궁금합니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
Security 에서 사용되는 Filter 의 @Bean 등록에 관하여 질문있습니다.
안녕하세요 선생님, 제가 읽은 spring security 문서와 제공해주신 ppt 의 내용에 약간 다른 점이 있어서 질문드립니다. [인증 관리자 - AuthenticationManager - 1] 강의 20:54 에 나오는 ppt 에는 CustomAuthenticationFilter 를 @Bean 으로 등록하라고 나옵니다. 그런데 제가 읽은 spring security 문서에서는 spring security 전용 Filter 는 단순히 @Bean 으로만 등록하면 servlet container 에 의해서 자동으로 Filter 로 등록되버리기 때문에 FilterRegistrationBean 까지 사용해서 이를 우회하라는 글을 본적이 있습니다. 참고: Architecture :: Spring Security 혹시 ppt 오타일까요?
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
RestAPI를 제공하는 서버에서 Redis + Session을 통해 인증을 시도하고 있는데 직렬화가 되지 않습니다.
안녕하세요 강의 잘 보고 있습니다.저는 지금 Rest API서버를 생성하고 인증을 하는 방식은 session으로 하고 session 저장소를 Redis로 옮겨 구현하고자 합니다. 그러나 강의와는 다르게 @EnableRedisHttpSession 어노테이션을 추가해도 Redis에 저장이 되지 않는 오류가 있는데 이를 어떻게 해결해야할지 모르겠어 질문을 드립니다. Redis가 아닌 Memory에 저장을 하였을때는 정상 동작하였으며 디버깅을 통해 문제의 원인을 파악해본 결과 SecurityContextImpl 객체에 대한 직렬화를 수행해주는 클래스가 존재하지 않아 오류가 발생하는 듯 합니다. 혹시 이 문제에 대해 도움을 받을 수 있을까요? 문제상황을 작성해놓은 포스팅과 프로젝트의 압축파일을 첨부해드리도록 하겠습니다.추가로 프로젝트 환경은 로컬에서 진행하였으며 H2 DB와 Redis를 사용하였습니다.https://goto-pangyo.tistory.com/286https://drive.google.com/file/d/1DccNwJWmUPBpe3KwsqxPp_VpYIAQRRaR/view?usp=sharing
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
@RestController가 아닌 @Controller 사용에 대하여
@Controller의 url들을 통해 원하는 화면들을 전환하는 방식으로 일을 진행 중 입니다.Security를 적용하려 보니 강의에는 @RestController뿐인데 @RestController는 페이지 전환에 적합하지 않다고 알고 있습니다. 그렇다면 @Controller에 Security를 적용할 수 없는겁니까?그리고 java version 17을 사용하셨는데 '왜 17을 사용하셨는지'와 '최신 버전인 22를 사용하면 어떠한 문제가 발생하는지'궁금합니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
@Data 사용
AccountDto, AccountContext 에서 @Data를 사용하고 있는데 @Data 안에는 setter가 들어가있어 사용을 지양해야한다고 알고 있습니다. 혹시 강사님께서는 예제라서 사용하신건지 아니면 @Data를 여기서 사용해도 문제가 없는건지 궁금합니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
AuthenticationManager에 초기화에 대해 질문있습니다
@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { return configuration.getAuthenticationManager(); }위 처럼 Bean 으로 등록하게되면내부 메서드에서 Bean으로 등록된Builder를 통해 등록하는거 까지는 이해했는데요.근데 여기서 setShareObject와 같은게 없는데 return http.build();빌드하게되면 HttpSecurity 메서드의 @Override protected void beforeConfigure() throws Exception { if (this.authenticationManager != null) { setSharedObject(AuthenticationManager.class, this.authenticationManager); } else { ObservationRegistry registry = getObservationRegistry(); AuthenticationManager manager = getAuthenticationRegistry().build(); if (!registry.isNoop() && manager != null) { setSharedObject(AuthenticationManager.class, new ObservationAuthenticationManager(registry, manager)); } else { setSharedObject(AuthenticationManager.class, manager); } } } 가 호출되어 여기서else 조건을 타 getSharedObject 로 AuthenticationManagerBuilder 빌더 클래스를 다시 꺼내와서 빌드를 하는데 이렇게 되면 http.build 과정의 인증관리자와스프링컨테이너에 있는 인증관리자는서로 다른건가요? 같다면 우리가 등록한 Bean이 build 과정에서 나올것같은데못찾겠습니다 ㅠㅠ..
-
해결됨스프링 시큐리티 완전 정복 [6.x 개정판]
SecurityContextHolderStrategy 설명해주신 부분에서 기존 방식 변경 방식에 대한 질문입니다.
안녕하세요, 24:00 에 말씀해주시는 SecurityContextHolderStrategy 사용하기부분에 기본방식과 변경방식 설명해주시는 부분에서 이해가 안되는 부분이 생겨 질문드립니다.기존방식과 변경방식의 구현된 소스코드를 보니 내부에서(SecurityContextHolder.crateEmptyContext() 내부) 도 결론적으로는 strategy.createEmptyContext() 를 delegate 하는 방식으로 호출 되는것을 보았습니다. 6.x, 5.x, 4.x 모두 동일한듯합니다. /** * Allows retrieval of the context strategy. See SEC-1188. * @return the configured strategy for storing the security context. */ public static SecurityContextHolderStrategy getContextHolderStrategy() { return strategy; } /** * Delegates the creation of a new, empty context to the configured strategy. */ public static SecurityContext createEmptyContext() { return strategy.createEmptyContext(); } AbstractAuthenticationProcessingFilter 쪽에서 successfulAuthentication 쪽에 로직dl 6.x, 5.7 이하 버전 대가 다른단것은 확인했는데 /** * Puts the <code>Authentication</code> instance returned by the authentication * manager into the secure context. */ protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException { this.logger.debug(LogMessage.format("Authentication success: %s", authResult)); SecurityContext context = this.securityContextHolderStrategy.createEmptyContext(); context.setAuthentication(authResult); this.securityContextHolderStrategy.setContext(context); this.securityContextRepository.saveContext(context, request, response); if (this.eventPublisher != null) { this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); } if (this.authenticationSuccessHandler != null) { this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authResult); } }/** * Puts the <code>Authentication</code> instance returned by the authentication * manager into the secure context. */ protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException { if (logger.isDebugEnabled()) { logger.debug("Authentication success: " + authResult); } SecurityContextHolder.getContext().setAuthentication(authResult); // Fire event if (this.eventPublisher != null) { eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent( authResult, this.getClass())); } if (authenticationSuccessHandler != null) { authenticationSuccessHandler.onAuthenticationSuccess(request, response, authResult); } }추측건데 strategy 쪽을 세팅할수있는 부분이 추가됨에따라 달라진 부분이라 생각이 되어 이부분도 말씀하신 의도와는 다를듯하여 /** * Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use * the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}. * * @since 5.8 */ public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) { Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null"); this.securityContextHolderStrategy = securityContextHolderStrategy; } 경쟁조건 때문이라고 설명하신 부분에서 말씀하시는 의도를 다시 한번 알수있을까요.
-
해결됨스프링 시큐리티 완전 정복 [6.x 개정판]
Rest 예외 처리 - RestAuthenticationEntryPoint / RestAccessDeniedHandler 스프링빈 등록 질문
안녕하세요 선생님 Rest 예외처리 편에서 선생님께서는 RestAuthenticationEntryPoint 와 RestAccessDeniedHandler을 따로 스프링 빈으로 등록하지 않고 객체를 생성하는식으로 하셨는데 제가 따로 스프링빈으로 등록하고 해도 잘 동작하던대 따로 빈으로 등록하지 않고 하신 이유가있을까요?해당 코드는 제가 빈으로 따로 등록하고 테스트 했던 코드입니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
예외처리에 관해 이해가 어려운 부분이 있습니다.
안녕하세요 강의 잘 보고 있습니다. 다름이 아니라 예외를 처리하는 부분에서 이해가 잘 가지 않는 부분이 이렇게 질문을 드립니다.스프링 시큐리티의 FilterChainProxy의 끝단에 예외를 처리하는 ExceptionTranslationFilter가 존재합니다. 해당 필터가 인가 예외를 처리하는 것까지는 이해하였습니다. 그러나 인증예외를 다루는 것이 조금 이해가 가지 않습니다. 스프링 시큐리티에서 제공하는 formLogin 인증을 포함한 모든 인증 방식은 ExceptionTranslationFilter앞에 존재합니다. 그럼에도 불구하고 인증 필터들에서 발생하는 예외들을 ExceptionTranslationFilter에서 처리를 합니다. 기존의 저는 예외가 발생할 즉시 바로 자신을 호출한 객체에게 예외를 반환하며 프로세스가 진행한다 알고 있는데 이는 스프링 시큐리티에서 인증예외를 처리하는 흐름과는 정 반대의 흐름입니다. 혹시 인증 필터에서 해당 예외가 발생할시 예외를 Throw하는 것이 아닌 다른방식으로 예외를 감싸서 ExceptionTranslationFilter까지 흘러가는 건가요? 아니면 제가 놓치는 부분이 있는걸까요?
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
섹션.8 메서드 기반 권한 부여 @PreAuthorize
안녕하세요? 섹션8. 메서드 기반 권한 부여 강의 보다가 잘 안되는 부분이 있어서 질문 드립니다! (16분 쯤에 설명 나오는 부분입니다!) @GetMapping("/user/{id}") @PreAuthorize("#id == authentication.name") public String authentication(@PathVariable(name = "id") String id){ return id; }해당 강의에서 user 로 로그인 시 위 url 로 접근이 가능했는데, 똑같이 해봤는데 403 이 떴습니다. 혹시나 해서 공유해주신 github 프로젝트로 해당 branch 로 체크아웃했더니 같은 현상이 나타납니다.이것저것 시도해보다가 스프링 공식페이지에서 @P 어노테이션에 대한 설명이 있길래 아래와 같이 도입해봤더니 정상동작합니다.@GetMapping("/user/{id}") @PreAuthorize("#id == authentication.name") public String authentication(@P("id") @PathVariable(name = "id") String id){ return id; }https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html 강의 하실 때보다 시큐리티 버젼이 또 올라가서 안되는 부분이 생긴 것일까요?아니면 제가 어떤 부분을 놓치고 있는걸까요? ㅠ
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
실무에서 spring boot 2.6.x 버전을 사용 하고 있는데요.
여기서 강의 나오는 버전 경우 spring security 버전이 6.x 버전입니다. 현재 실무에서 사용하고 있는 spring boot 버전이 2.6.x 인데요. boot 업그레이드 하지 않고 security 버전을 6.x 버전으로 올려도 괜찮을까요?... implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '3.2.5' build.gradle 파일에 이렇게 수정해서 올렸더니 @EnableWebSecurity같은 중요한 객체가 import가 안되는 문제가 생겨서요 ㅠㅠ
-
해결됨스프링 시큐리티 완전 정복 [6.x 개정판]
AuthenticationManager 사용방법에 대해 질문있습니다.
안녕하세요 강의 잘 보고 있습니다.다름이 아니라 강의를 보며 궁금한 점이 생겨 이렇게 질문드립니다.영상및 강의자료에서는 Authentication Manager를 사용할때 CustomFilter를 다루는 부분이 나옵니다. 이때 첫번째 방법(HttpSecurity 사용)은 필터를 Bean으로 등록하는 것이 아닌 직접 필터 객체를 생성하고 Authentication ManagerBuilder를 통해 직접 build한 Authentication Manager에 등록하고 두번째 방법(직접 생성)은 필터를 빈으로 등록하고 Authentication Manager관련 프로세스는 스프링 시큐리티에 위임한다는 느낌을 받았습니다. 이때 이 두가지 방법의 차이는 어떤 것이 있을까요? Authenticaion Manager를 직접 생성하기에 세밀한 설정이 가능하다는 차이가 있고 없고인가요?스프링 시큐리티의 버전이 변경되면서 필터를 Bean으로 등록해 사용하도록 권장하고 있다고 알고 있습니다. 이러한 관점에서 보았을때는 두번째 방법이 스프링 시큐리티 측에서 권장하는 방법으로 이해해도 될까요?
-
해결됨스프링 시큐리티 완전 정복 [6.x 개정판]
PPT 강의 자료는 어디 있을까요...?
안녕하세요 선생님~! 혹시 PPT 강의 자료는 어디 있을까요...? ㅠㅠ
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
react 와 같은 별개의 프론트가 있는 경우 csrf
이런 경우에는 rest 방식으로 로그인할때, csrf 값을 처리할 수 없을거 같은데요. same-site 방식으로 처리하면 되는걸까요?
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
강의 교안에서 SessionManagementFilter 이미지 질문
강의 교안의 동시 세션제어필터 로직의 흐름도 그림에서SessionManagementFilter가 세션 만료 설정 플래그를 설정하는 그림에서 혼동이 있어서 질문드립니다. 현재 스프링시큐리티 6 이후 기본동작에서는 SessionManagementFilter가 기본 동작하지 않는 것으로 알고 있습니다. 실제로 세션 관련 설정을 이것저것 바꿔봐도 SessionManagementFilter가 필터체인에 추가되지 않더군요.(실제로 강의에서도 이 부분을 언급하신 것을 확인했고, 공식문서에서도 확인했습니다.)대신 UsernamePasswordAuthenticationFilter(정확히는 이것의 상위 클래스인 AbstractAuthenticationProcessingFilter)와 같은 곳에서 명시적으로 sessionAuthenticationStrategy를 호출하여 세션 관련 처리를 위임시키는 식으로 처리하는데요.현시점 기본 동작 관점에서 보면 강의 교안에 나와있는 흐름도를 보면 SessionManagementFilter로 그림이 나와잇는 부분은 UsernamePasswordAuthenticationFilter와 같은 최초 로그인을 담당하는 필터에서 인증후 strategy를 통해 만료플래그가 설정되는 것으로 나타나게 하는 것이 좀 더 정확하지 않을까 싶어서 질문을 드립니다.