안녕하세요 이렇게 좋은 Spring Security에 애를 많이 먹던 도중 늦게나마 열심히 듣고 있는 사람입니다. 강의를 들으면서 Spring Security 6.0 이상 버전으로 혼자 마이그레이션 해보며 공부를 진행하는데요.. 다른 분들은 모르겠지만 저는 6.0 이상 버전에서의 다중 보안 설정에서 애를 좀 먹어서.. 혹시나 저 같으신 분들이 있으실까봐 글을 남깁니다..! 다름이 아니라 Spring Security 6.0 이상 버전에서는 먼저 오버라이드해서 함수를 구현하는 것이 아니라 컴포넌트화 시켜서 진행합니다. 또한 HttpSecurity 안의 내용을 구현하는데 변경점이 있다는 것이 가장 큰 차이점인 것 같습니다. 예를 들어 UserSecurityConfig, AdminSecurityConfig를 만들어서 각 경우에 따라 다른 설정을 적용하고 싶은 경우에 두 가지의 config 파일을 만들 수 있다고 가정하면.. 저의 경우에는 AdminSecurityConfig에서 지정한 부분이 권한 정보에 따라 접근이 막히지 않고 다 접근이 가능한 ("/admin/pay"를 user가 접근 가능) 상황이었습니다. 뭐가 문제인지 한참을 찾던 도중 https://docs.spring.io/spring-security/reference/servlet/configuration/java.html 공식 문서를 통해 답을 찾았습니다. 간략하게 해결법부터 말씀드리자면 path로 접근 제한을 하는 경우에 http.securityMatcher()를 사용해야 한다는 점 입니다. 이렇게 하면 아주 잘 구분이 되더군요..! 혹시나 저처럼 하시는 분이 계실까봐 남깁니다..! @Bean @Order(0) public SecurityFilterChain adminFilterChain(HttpSecurity http) throws Exception{ http .securityMatcher("/admin/pay") .authorizeHttpRequests(request -> request.anyRequest().hasRole("ADMIN")); return http.build(); } @Bean @Order(1) public SecurityFilterChain systemFilterChain(HttpSecurity http) throws Exception{ http .securityMatcher("/admin/**") .authorizeHttpRequests(request -> request .anyRequest().hasAnyRole("SYS", "ADMIN")); return http.build(); } @Bean @Order(2) public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ http .authorizeHttpRequests(request -> request .requestMatchers(antMatcher("/user/**")).hasRole("USER") .anyRequest().authenticated());
안녕하세요 현재 AjaxAuthenticationFilter에 대해 수강 시작을 하고 있는 중입니다. 웹사이트에서 from 방식과 ajax 방식은 동기와 비동기 차이인 것으로 배웠습니다! 또한, 공부해보니 form 방식은 페이지가 이동시 파라미터 및 자원들이 모두 이동하여 리소스가 더 많이 든다라는 점이 차이점인 것 같습니다.! 여기서 갑자기 든 의문점으로.. 주로 사이트들이 회원가입 또는 로그인을 눌렀을 때 해당 로그인 페이지가 따로 있는 것이 일반적으로 보이는데 Ajax 로그인으로 활용한 대표적 사이트의 reference가 있을까요..? Ajax 로그인의 장점으로 비동기, 리소스 낭비 감소 이외의 다른 추가적 장점이 있을까요?
문제가 발생한건 아니고 단순 질문입니다! 테스트 짜실 때 보면, // 1번 코드 assertEquals("상수값", findComment.getAuthor()); // 2번 코드 assertEquals(addComment.getAuthor, findComment.getAuthor()); 1번처럼 상수값과 비교를 많이 하시는데, 저는 2번처럼 저장하려고 했던 객체와 실제로 저장된 후 리턴된 객체간의 비교를 많이 하는 것 같습니다. 2번이 유지보수의 측면으로 봤을 때 더 좋아보이는데 1번 스타일로 테스트 코드를 짜는 이유가 있으실까요?
안녕하세요. 선생님. 선생님 강의로 많이 배우고 있네요. UrlFilterInvocationSecurityMetadataSource 를 직접 구현하여 DB와 연동하는 것을 보여주셨는데. 이 클래스에 Resouce 인가 설정을 위한 클래스의 멤버 변수로 LinkedHashMap<RequestMatcher, List<ConfigAttribute>> requestMap 을 사용하네요. 만약 DB에 Resource, Role 인가 설정 변경 시 reload()가 불렸을 때 DB에서 모두 가져와 requestMap 에 put 하는데 이것이 multi thread 에 safe 한지요? 만약 thread에 safe 하지 않다면 좋은 방법이 있는지요? lock을 쓰기에는 read 요청이 많아 부담스러울 것 같다는 느낌이 있네요. 강의에서 Role 추가 시 실시간 설정 반영은 하지 않았지만 RoleHierarchy 또한 마찬가지 인 것 같아요. 운영 시 거의 변경이 안되기 때문에 그냥 놔두는게 가장 좋은 방법인지? 선생님의 의견을 알고 싶어요. 감사합니다.
안녕하십니까, 스프 강의 잘 듣고 있습니다! spring에 대해서 알고 싶은 학생입니다. 강의를 듣고 있는데, 패키지끼리? 빠르게 왔다갔다 하시던데 그런 부분이 이해가 어렵다면 나프 1탄, 2탄을 듣는 게 도움이 될까요? 아니면 스프 강의를 일단 한 번 가볍게 듣고 한 번 더 듣는 게 도움이 될까요? 그리고 나프 1탄, 2탄은 어떤 강의인지 자세하게 알고 싶습니다!
증상 ### 로그인(일반 회원) POST http://localhost:8080/api/login Content-Type: application/json X-Requested-With: XMLHttpRequest { "username": "user", "password": "1111" } ### 로그인(매니저) POST http://localhost:8080/api/login Content-Type: application/json X-Requested-With: XMLHttpRequest { "username": "manager", "password": "1111" } ### messages 요청 GET http://localhost:8080/api/messages Content-Type: application/json X-Requested-With: XMLHttpRequest http 파일을 작성하고 로그인 요청에 성공했음에도 성공 응답 및 사용자 정보 dto가 오도록 했는데, 쿠키가 오지 않는 문제가 있었습니다. 원인 원인은 AbstractAuthenticationProcessingFilter 의 기본 SecurityContextRepository가 RequestAttributeSecurityContextRepository이기 때문입니다. 그동안 폼 인증에서 우리가 세션을 통해 인증을 할 수 있었던 것은 스프링시큐리티가 기본적으로 등록해준 UsernamePassowordAuthenticationFilter가 저 SecurityContextRepository 구현체로 DelegatingSecurityContextRepository(HttpSessionSecurityContextRepository(), RequestAttributeSecurityContextRepository()) 를 넣어줬기 때문입니다. 또 우리가 AuthenticationSuccessHandler, AuthenticationFailureHandler를 커스텀하게 만들었다면 이를 수동으로 등록하는 코드를 작성해줘야하는 이유도 이와 같습니다. 기본 구현체가 위와 같기 때문입니다. @Bean fun ajaxLoginProcessingFilter(): AjaxLoginProcessingFilter { val filter = AjaxLoginProcessingFilter(objectMapper, authenticationManager()) filter.setSecurityContextRepository(securityContextRepository()) filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()) filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()) return filter } @Bean fun securityContextRepository(): SecurityContextRepository = DelegatingSecurityContextRepository(HttpSessionSecurityContextRepository(), RequestAttributeSecurityContextRepository()) @Bean fun ajaxAuthenticationProvider() = AjaxAuthenticationProvider(userDetailsService, passwordEncoder()) @Bean fun ajaxAuthenticationSuccessHandler() = AjaxAuthenticationSuccessHandler(objectMapper) @Bean fun ajaxAuthenticationFailureHandler() = AjaxAuthenticationFailureHandler(handlerExceptionResolver) @Bean fun ajaxAuthenticationEntryPoint() = AjaxAuthenticationEntryPoint(objectMapper) @Bean fun ajaxAccessDeniedHandler() = AjaxAccessDeniedHandler(objectMapper) 혹시 저처럼 최신 스프링 시큐리티 환경에서 실습하시면서http 요청 실습에서 로그인 시 쿠키가 전송 안 되시는 분들은 이 작업을 해보시길 바랍니다. SecurityContextRepository 구현체를 생성하여, 등록해보시는 것을 추천드립니다.
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"> 이부분에서 에러 내용이 Element 'bean' cannot contain text content. The content type is defined as element-only. 라고 나오는데 뭐가 문제일까요? pom.xml에서 <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.4.1</version> </dependency> 이렇게 설정했습니다.
MemberMapper인터페이스의 public Member registerCheck(String memID); public Member getMember(String memID); MemberMapper.xml의 <select id="registerCheck" resultType="kr.board.entity.Member"> select * from mem_tbl where memID=#{memID} </select> <select id="getMember" resultType="kr.board.entity.Member"> select * from mem_tbl where memID=#{memID} </select> 요거 두개는 동일한게 맞을까요?
스프링 시큐리티가 던지는 예외는 RestControllerAdvice로 처리하려면 따로 설정을 만져야하는걸로 아는데 강사님 강의에서는 별다른 설정없이 이런식으로 예외처리가 되고있는데 어느 부분때문에 가능한건가요 ? ㅠㅠ 혹시 로그인시 서비스단에서 token 생성 처리를 하고있어서 예외처리가 될수있는건가요 ??
이렇게 바꿔봤는데 Body = {"code":"400","message":"잘못된 요청입니다.","validation":[{"fieldName":"content","errorMessage":"내용을 입력해주세요"},{"fieldName":"title","errorMessage":"제목 을 입력해주세요"}]} 이렇게 배열로 응답이 갈수있게 바꿔봤는데 괜찮을까요?
@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{return http.authorizeHttpRequests().requestMatchers("/auth/login").permitAll() .anyRequest().authenticated() .and().csrf(AbstractHttpConfigurer::disable) .build(); } 기존의 강의에 나온 위 코드를 실행하게 되면, This is because there is more than one mappable servlet in your servlet context: {org.springframework.web.servlet.DispatcherServlet=[/], org.h2.server.web.JakartaWebServlet=[/h2-console/*]}. 위와 같은 DispatcherServlet과 h2-console의 서블릿이 하나 이상 매핑되어 나는 오류라고 나옵니다. @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception{ http.authorizeHttpRequests((authz) -> { try { authz .requestMatchers(new MvcRequestMatcher(introspector,"/auth/login")).permitAll() //애는 권한 없이도 허용 .anyRequest().authenticated() //나머지는 인증해 .and() //csrf쪽으로는 builder가 이어지지 않기 때문에 and로 이어준다. .csrf(AbstractHttpConfigurer::disable); } catch (Exception e) { throw new RuntimeException(e); } }); return http.build(); } 그래서 검색 결과 위와 같이 작성하게 되면 정상적으로 실행되게 됩니다. - 질문 제가 코드를 기존에 SecurityFilterChain 외 잘못 작성한 부분이 존재해서 위와 같이 코드를 작성해야 하는 것인지, 아니면 그 사이에 이렇게 작성되도록 변경된 것인지 앞으로도 지속적으로 검색해보겠지만... 현재까진 답을 찾지 못해 질문드립니다. 2. h2-console의 경우 데이터베이스 관련 서블릿이고, DispatcherServlet은 웹 애플리케이션의 컨트롤러 역할을 하는 서블릿인걸로 알고 있는데 용도가 다른 두 서블릿의 매핑 혼동이 일어나는 이유가 궁금합니다... *무지한 한 생명체의 질문은 천천히 쾌차하시고 삶의 여유를 되찾으신 다음 답변해주시면 감사하겠습니다!
안녕하세요 강의명-소스브랜치 정리한 엑셀 파일에서 3) 어노테이션 권한 설정 - @PreAuthorize, @PostAuthorize, @Secured, @RolesAllowed 강의의 브랜치명이 ch05-9가 아니라 ch05-8인것 같습니다. Account 클래스의 userRoles에 붙은 어노테이션이 8에서 9로 넘어갈때 달라져서 강의 내용이 재연이 안됩니다. 확인 부탁드립니다.