묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 시큐리티
파트4-5강의 실습중 manager로 로그인하고난후 /api/messages를 호출시 Authentication가 Anonymous토큰상태가 되어버립니다.
실습중 manager로 로그인해도 계속 401에러가발생하여/api/messages에 대해 permitAll권한을주어 테스트해보았는데 위에 스크린샷처럼 Anonymous토큰상태여서 발생하는듯한데 프로바이더에서 토큰처리는 완료한 상태입니다.로그인도 정상적으로 되고있구요. 뭔가 해야 할 작업이 빠진걸까요?스프링은 3.03버젼이고 스프링시큐리티도 6버전대입니다package io.security.corespringsecurity.security.config; import io.security.corespringsecurity.security.common.AjaxAccessDeniedHandler; import io.security.corespringsecurity.security.common.AjaxLoginAuthenticationEntryPoint; import io.security.corespringsecurity.security.filter.AjaxLoginProcessingFilter; import io.security.corespringsecurity.security.habdler.AjaxAuthenticationFailureHandler; import io.security.corespringsecurity.security.habdler.AjaxAuthenticationSuccessHandler; import io.security.corespringsecurity.security.provider.AjaxAuthenticationProvider; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @Order(0) @RequiredArgsConstructor public class AjaxSecurityConfig { private final AuthenticationConfiguration authenticationConfiguration; @Bean public AjaxAuthenticationProvider ajaxAuthenticationProvider(){ return new AjaxAuthenticationProvider(); } @Bean public AuthenticationSuccessHandler ajaxAuthenticationSuccessHandler(){ return new AjaxAuthenticationSuccessHandler(); } @Bean public AuthenticationFailureHandler ajaxAuthenticationFailureHandler(){ return new AjaxAuthenticationFailureHandler(); } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{ http .authorizeHttpRequests(requests -> requests .requestMatchers("/api/**").permitAll() .requestMatchers(HttpMethod.GET,"/api/messages").hasRole("MANAGER") .anyRequest().authenticated()); http .exceptionHandling() .authenticationEntryPoint(new AjaxLoginAuthenticationEntryPoint()) .and() .addFilterBefore(ajaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class); http.csrf().disable(); return http.getOrBuild(); } @Bean public AccessDeniedHandler ajaxAccessDeniedHandler(){ return new AjaxAccessDeniedHandler(); } @Bean public AuthenticationManager authenticationManager() throws Exception{ ProviderManager providerManager = (ProviderManager)authenticationConfiguration.getAuthenticationManager(); providerManager.getProviders().add(ajaxAuthenticationProvider()); return providerManager; } @Bean public AjaxLoginProcessingFilter ajaxLoginProcessingFilter() throws Exception{ AjaxLoginProcessingFilter ajaxLoginProcessingFilter = new AjaxLoginProcessingFilter(); ajaxLoginProcessingFilter.setAuthenticationManager(authenticationManager()); ajaxLoginProcessingFilter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()); ajaxLoginProcessingFilter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()); return ajaxLoginProcessingFilter; } }package io.security.corespringsecurity.security.provider; import io.security.corespringsecurity.security.service.AccountContext; import io.security.corespringsecurity.security.token.AjaxAuthenticationToken; import io.security.corespringsecurity.util.PBKDF2Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; @Component public class AjaxAuthenticationProvider implements AuthenticationProvider{ @Autowired private UserDetailsService userDetailsService; @Transactional @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String password = (String)authentication.getCredentials(); AccountContext accountContext = (AccountContext)userDetailsService.loadUserByUsername(username); try { if(!PBKDF2Util.validatePassword(password, accountContext.getAccount().getPassword())){ throw new BadCredentialsException("BadCredentialsException"); } } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new RuntimeException(e); } return new AjaxAuthenticationToken(accountContext.getAccount(), null, accountContext.getAuthorities()); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(AjaxAuthenticationToken.class); } } package io.security.corespringsecurity.security.filter; import com.fasterxml.jackson.databind.ObjectMapper; import io.security.corespringsecurity.domain.AccountDto; import io.security.corespringsecurity.security.token.AjaxAuthenticationToken; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.thymeleaf.util.StringUtils; import java.io.IOException; public class AjaxLoginProcessingFilter extends AbstractAuthenticationProcessingFilter { private ObjectMapper objectMapper = new ObjectMapper(); public AjaxLoginProcessingFilter() { super(new AntPathRequestMatcher("/api/login")); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if(!jsAjax(request)){ throw new IllegalStateException("Authentication is not supported"); } AccountDto accountDto = objectMapper.readValue(request.getReader(), AccountDto.class); if(StringUtils.isEmpty(accountDto.getUsername()) || StringUtils.isEmpty(accountDto.getPassword())){ throw new IllegalArgumentException("Username or Password is empty"); } AjaxAuthenticationToken authenticationToken = new AjaxAuthenticationToken(accountDto.getUsername(), accountDto.getPassword()); return getAuthenticationManager().authenticate(authenticationToken); } private boolean jsAjax(HttpServletRequest request) { if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){ return true; } return false; } }
-
미해결스프링부트 시큐리티 & JWT 강의
Facebook 로그인 버튼만든 후 error(Sorry...) 발생시
인증 및 계정 만들기 > 수정 에서 Email 권한 추가해주어야 오류 안나네요.
-
미해결스프링 프레임워크는 내 손에 [스프1탄]
자바11과 전자정부프레임워크4.1 사용해도될까요?
자바11버전이랑 전자정부프레임워크4.1를 사용중인데이거 그대로 사용해도될까요?아니면 자바를 8로 변경해서 수업을 들어야할까요?
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
Validation Map으로 구현된걸 List로 바꿔봤는데 이 방식이 맞을까요?
이렇게 바꿔봤는데 Body = {"code":"400","message":"잘못된 요청입니다.","validation":[{"fieldName":"content","errorMessage":"내용을 입력해주세요"},{"fieldName":"title","errorMessage":"제목 을 입력해주세요"}]} 이렇게 배열로 응답이 갈수있게 바꿔봤는데 괜찮을까요?
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
안녕하세요!
혹시 시즌3 자료는 받을수 없을까요?!
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
SecurityFilterChain 서블릿 매핑 오류 관련...
@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 강의 브랜치 오류
안녕하세요강의명-소스브랜치 정리한 엑셀 파일에서3) 어노테이션 권한 설정 - @PreAuthorize, @PostAuthorize, @Secured, @RolesAllowed 강의의 브랜치명이 ch05-9가 아니라 ch05-8인것 같습니다. Account 클래스의 userRoles에 붙은 어노테이션이 8에서 9로 넘어갈때 달라져서 강의 내용이 재연이 안됩니다.확인 부탁드립니다.
-
미해결스프링부트 시큐리티 & JWT 강의
실수로 google auth 시크릿 키를 깃에 업로드 했어요
업로드 하고 구글 메일로 시크릿키가 노출되었다고 메일이 와서 10분 내로 대시보드에 있는 프로젝트를 닫았는데, 30일 뒤에 닫힌다고 알람이 오고, 다시 대시보드를 보니까 사진과 같이 뜨던데 이후에 문제가 발생할까요...?ㅠㅠㅠㅠ
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
@ConfigurationProperties 사용 시 질문 드립니다.
제가 아직 초보 개발자라 막연히 setter 사용은 지양하는게 좋다고 배워서 실무에서는 다른지 궁금합니다.setter 를 열어두면 빈으로 등록된 AppConfig 의 불변성을 보장할 수 없게 되는게 아닌가 해서 질문드립니다.https://mangkyu.tistory.com/189위 블로그를 보면 @ConfigurationProperties 를 setter 없이 생성자로 할 수도 있는것 같아서요.혹시 제가 너무 setter 사용을 지양하라는 말에 매몰돼있는건 아닐까 고민도 되네요.
-
미해결스프링 프레임워크는 내 손에 [스프2탄]
com.mysql
43강 4분 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId> </dependency> 저는 이부분에 처음부터 이렇게 뜨는데 왜그런걸까요?
-
해결됨스프링 시큐리티
FilterSecurityInterceptor에서 AuthenticationManager 주입 받는 이유
안녕하세요 강사님 4) 웹 기반 인가처리 DB 연동 - FilterInvocationSecurityMetadataSource (1) 수업을 듣다가 질문드립니다. FilterSecurityInterceptor에서 AuthenticationManager 주입 받는 이유가 궁금합니다. 인증은 앞의 필터를 지나면서 이미 완료가 되었고, FilterSecurityInterceptor는 인증이 끝난 뒤에, 권한 정보를 조회해서 체크하는 곳이고, 인증 정보는 SecurityContextHolder에서 꺼내면 되는데, AuthenticationManager로 뭘하려고 주입받는 것인지 궁금합니다. AbstractSecurityInterceptor 코드를 살펴보니, authenticateIfRequired 메서드에서 SecurityContextHolder에서 꺼낸 Authentication 객체가 isAuthenticated 가 false일때 AuthenticationManager에 Authentication 객체를 넘겨서 재인증을 시도하고 있습니다. private Authentication authenticateIfRequired() {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication.isAuthenticated() && !this.alwaysReauthenticate) {if (this.logger.isDebugEnabled()) {this.logger.debug("Previously Authenticated: " + authentication);}return authentication;} else {authentication = this.authenticationManager.authenticate(authentication);if (this.logger.isDebugEnabled()) {this.logger.debug("Successfully Authenticated: " + authentication);}SecurityContextHolder.getContext().setAuthentication(authentication);return authentication;}} 그런데, 이미 앞에서 인증 과정을 거친 결과가 isAuthenticated == false인 상태에서, 재인증을 시도하는 것이 무슨 의미가 있는지 궁금합니다. 결과가 달라지는 케이스가 있는건지, 재인증이 목적이 아닌건지... 아니면 인증을 처리하는 필터가 앞에 없을때를 가정하는건지...궁금합니다. 답변 주시면 감사하겠습니다.
-
미해결[초급] 찍어먹자! 코틀린과 Spring Security + JWT로 회원가입 만들기
1 : N 필드 `memberRole` 에 @OneToMany 옵션 cascade 미사용, 컬랙션 null 초기화 에 대한 질문입니다.
class Member( ... ) { @OneToMany(fetch = FetchType.LAZY, mappedBy = "member") ⬅️Q1:"cascade 없음 이유" val memberRole: List<MemberRole>? = null ⬅️Q2: "null 초기화"(mutableListOf() 누락) } Q1:cascade 미사용:강의 컨샙에 맞춰 쉬운 예제 구성을 목적으로 컬랙션 필드에 Cascade 설정을 안하신게 아닐까 추측했지만, 한편으로 다른 구현방법에 대한 다른이유가 있으신 것인지 강의에 언급되지 않은 부분을 여쭤보고 싶었습니다.Q2:컬랙션 null 초기화:일반적인 JPA 예제에서는 JpaEntity 의 1:N 관계 필드는 Collection 초기화를 하더라구요. null 로 초기화 할 때의 장점 이라던지, 다른 이유가 있는지 궁금해서 남기게 되었습니다. 읽어주셔서 감사합니다.
-
미해결스프링 시큐리티
ajax 요청 응답에 대한 문의
안녕하세요 3) 인증 처리자 - AjaxAuthenticationProvider 수업에서 ajax 요청 날린 뒤 응답이 <Response Body is Empty>가 안뜨고, HTML 파일(정상적인 home 화면)이 응답되는 현상이 있습니다. https://github.com/kickhen/springsecuritypractice/tree/master 왜 저는 html이 리턴되는건지 무엇을 빼먹었는지 궁금합니다. 알려주시면 감사하겠습니다.
-
해결됨스프링 시큐리티
SecurityConfig에서 사용하는 빈 주입 방식 질문
안녕하세요 3) 인증 처리자 - AjaxAuthenticationProvider 수업 듣던중 질문 남깁니다. SecurityConfig에서 어떤건 @Component로 빈 생성한 뒤에 Autowired로 주입받고(ex)CustomAuthenticationSuccessHandler ), 어떤건 @Component 안달고 직접 new 생성자 호출해서 @Bean 어노테이션으로 빈 등록을 하고 계시는데 (ex:CustomAuthenticationProvider 또는 FormAuthenticationProvider) 빈 주입하는 방식이 다른 이유가 궁금합니다. 일단 제가 해봤을 때 CustomAuthenticationProvider 에 @Component를 달면, SecurityConfig에 @Bean으로 등록한 PasswordEncoder 관련해서 빈 생성이 꼬이게 되는 것은 확인했는데요 단지, @Component를 달아보니까 꼬이더라 라는 이유를 넘어서서, SecurityConfig에서 사용하는 Bean을 주입하는 방식에 대해 구분하는 기준이 있다면 가르쳐주시면 감사하겠습니다.
-
미해결스프링 시큐리티
FilterSecurityInterceptor deprecated
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. FilterSecurityInterceptor deprecated 가 돼서 AuthorizationFIlter 를 사용하라고 해서 @Bean 으로 등록하려고 했습니다. @Bean public AuthorizationFilter authorizationFilter() throws Exception { AuthorizationFilter filter = new AuthorizationFilter(authorizationManager(authenticationConfiguration)); filter.set } 여기서 setSeucirtyMetadataSource 같은 메서드가 없어서 어떻게 해야할지 잘 모르겠습니다...
-
미해결스프링 시큐리티
Ajax 로그인 질문 있습니다
Ajax 로그인 시도 시강사님과 다른 방식으로 응답이 오는데정상적으로 작동한 것이 맞는지 궁금합니다.
-
미해결스프링 시큐리티
다중 필터 구현 시, antMatchers 사용
예제에서는 antMatcher('/admin/**') 이런식으로특정 url 하나만 지정을 했는데혹시 '/user/**' 도 같이 Match 시키고 싶은데antMatcher 는 1개만 처리해주는 것 같습니다.꼭 새로운 FilterChain 을 생성해서 설정해야하나요?
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
안녕하세요 호돌맨님 예외처리2 에서 질문이 있습니다.
좋은 강의 정말 감사드립니다.호돌맨님 강의덕분에 기존에 공부했던 지식들 정리도 하고 더 좋은 설계가 어떤건지 잘 배우고 있습니다.제가 예외처리2 강의를 보고 컨트롤러 테스트를 하다가 게시글 작성 실패케이스에서 오류가 생겨서 질문드립니다. PostControllerPostCreatePostControllerTest글 작성 요청 시 제목, 내용 모두 null 인 케이스 테스트입니다.이 테스트에서 실패합니다.로그는 아래와 같습니다.응답 바디에도 아무것도 오지 않습니다.로그를 쫓아서 ErrorResponse 에 브레이크 포인트를 찍어봤습니다. ErrorResponse여기서 validation 이 null로 잡힙니다.PostControllerAdvice이쪽 ExceptionHandler 작성할 시점에 생성자에 validation 을 매개변수로 받지 않았을땐 오류가 발생하지 않았는데 validation 을 매개변수로 받고 나서 오류가 생기는거면 @Builder 가 ErrorResponse 의 validation 초기화를 무시하고 null 값으로 생기는 현상 같습니다.그래서 따로 빌더 안붙인 validation 을 받지 않는 생성자를 만드니 잘 돌아갑니다.그런데 강의 마지막에 전체 테스트 한번 돌리고 마무리 하신것 같은데 호돌맨님은 어떻게 테스트 실패가 안뜬건지 궁금합니다. 그리고 혹시 더 좋은 방법이 있는지 방향을 알려주시면 감사하겠습니다.
-
미해결스프링 시큐리티
커스텀 필터 등록 시, ApplicationFilterChain 에 등록
안녕하세요 강의 잘 듣고 있습니다! SecurityConfig에서 커스텀 필터 등록 시 @Bean 형식으로 필터객체를 생성하여 등록하면 ApplicationFilterChain에 등록되는게 맞는걸까요? Bean 만 선언한다면 ApplicationFilterChain 에 등록되고addFilter(customFilter) 를 추가해주면 ApplicationFilterChain 리스트에도 등록되고SecurityFilterChain 에도 등록이 됩니다.문제는 제가 만든 커스텀 필터는, 특정 URL 에서는 동작 안하게끔 구현하고 싶은데@Bean으로 등록했기 때문에 ApplicationFilterChain에 등록되어 어떤 요청이 들어오든 동작하는 게 문제입니다. @Bean 방식이 아닌addFilter(New CustomFilter()) 로 하면 SecurityFilterChain에만 등록되긴 하는데 CustomFilter 는 스프링 컨테이너에 등록이 안되기 때문에 다른 Resource 객체들을 주입받지 못하는 상황입니다.결론은 ApplicationFilterChain에는 추가 안하고 SecurityFilterChain에만 커스텀 필터를 추가하고 싶은데 New 방식 말고는 없는 것인지가 궁금합니다!
-
해결됨스프링 시큐리티
스프링부트3.1 / 시큐리티6.1 관련하여 문의드립니다.
http.authorizeRequests() .requestMatchers(new AntPathRequestMatcher("/")).permitAll() // 기본 경로는 로그인을 안하고도 볼 수 있어야함 .requestMatchers(new AntPathRequestMatcher("/mypage")).hasRole("USER") //유저 권한이 있는 사람만 접근 가능 .requestMatchers(new AntPathRequestMatcher("/messages")).hasRole("MANAGER") .requestMatchers(new AntPathRequestMatcher("/config")).hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin(); return http.build(); @Bean static final public InMemoryUserDetailsManager kk() { //DB연동을 안할 경우, 테스트 용으로 하는 것이다. UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("1111") .roles("USER") .build(); UserDetails admin = User.withDefaultPasswordEncoder() .username("admin") .password("1111") //.roles("ADMIN","USER") .roles("ADMIN") .build(); UserDetails manager = User.withDefaultPasswordEncoder() .username("manager") .password("1111") .roles("MANAGER") .build(); return new InMemoryUserDetailsManager(user, admin, manager); // 아래는 컨트롤러 입니다. @GetMapping("/") public String getInts() { System.out.println("path: / /n"); return "index"; } @GetMapping("/mypage") public String getInt23() { System.out.println("path: /mypage /n"); return "index"; } @GetMapping("/config") public String getInt45() { System.out.println("path: /config /n"); return "index"; } 안녕하세요 해당 config파일 설정에 의하여 프로젝트는 문제 없이 잘 돌아가고는 있습니다.하지만, 초기 경로 "/" 으로 갈때에는 모두 허용이라는 permitAll()이 작동하기 전에 무조건 시큐리티 내장 "/login" 페이지로 이동 후, 아이디/비밀번호 입력시 "/" 경로를 타게 됩니다. /login을 거치지 않도록 하기 위한 방법이 있을까요? https://drive.google.com/file/d/1DljHlHOwmlCuiFrCh5NMB5TfYhMh23Bj/view?usp=sharing해당 링크는 크롬 브라우저에서 페이지 테스트한 영상입니다!!