수강이 제한됩니다.
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 시큐리티
강사님 안녕하세요!질문있습니다.
우선 강의 잘 보고있습니다 어렵지만 열심히 배우고있습니다. security 쪽이..왜 이렇게 어려운지..ㅜㅜ,.. 다름아니라 질문이 생겨서 이렇게 작성 합니다. 너무 초보적인 질문이고..이상한 질문이라 생각하실 수 있으실것 같긴한데요.. CustomAuthenticationProvier 쪽 보시면 AccountContext 객체를 가져오려고 UserDetailsService 를 주입받고 userDetailsService 의 loadUserByUsername 을 호출하여 가져오는부분에서요.. username이 제가 로그인 하려한 id를 뜻하는거지요..? username 이라하니..웬지 고객성함 이런거 뜻하기도 하는거같고..제 생각에는 userId 라던가 userEmail 같은 pk를 뜻하는 이름이 더 잘 어울릴것 같은데.. username은 그냥 이름만 username이고 개발자가 username을 id라던지 email이라던지 pk값으로 생각하고 써야하나요?? 이상한 질문인데 급 궁금해져서 여쭤봐요=_=.. 앞강의에서 이러한 질문이 해소되는 강의가 있을지 모르겠네요ㅜㅜ..지금 듣고는 있는데 앞강의를 안듣고 일단 실전 한번 부딪히고 다시 이론 수업 들을려고 하고 있어서 앞전강의부분에 이러한 얘기를 언급하셨다면 죄송합니다!!
- 미해결스프링 시큐리티
11:20 정도 질문이요
1. 인증 예외의 대한 나의 이해 - 로그인시 실패시 에러처리 크게 두가지 1. 인증실패후 -> 대부분 로그인창으로 이동 2. 익명의 사용자 세션저장? 이렇게 이해를 하는게 맞을까요..? - 추가로.. 2번 익명사용자 저장하는 용도가 뒤에 강의에서 로그인 성공시 내가 인증받지 못한 url로 넘어가는 용도로 저장을한다? 다른 용도도 포함이지만 이게 맞을까요
- 미해결스프링 시큐리티
IllegalArgumentException: authenticationManager must be specified 에러가 납니다.
[SecurityConfig] package io.security.corespringsecurity.security.configs; import io.security.corespringsecurity.security.filter.AjaxLoginProcessingFilter; import io.security.corespringsecurity.security.handler.CustomAccessDeniedHandler; import io.security.corespringsecurity.security.provider.FormAuthenticationProvider; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; 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; import org.springframework.web.filter.CharacterEncodingFilter; import javax.persistence.Access; @Configuration @EnableWebSecurity @Slf4j public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AuthenticationDetailsSource authenticationDetailsSource; @Autowired private AuthenticationSuccessHandler customAuthenticationSuccessHandler; @Autowired private AuthenticationFailureHandler customAuthenticationFailureHandler; @Bean public FormAuthenticationProvider authenticationProvider() { return new FormAuthenticationProvider(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authenticationProvider()); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations()); } @Override protected void configure(final HttpSecurity http) throws Exception { CharacterEncodingFilter filter = new CharacterEncodingFilter(); http .authorizeRequests() .antMatchers("/","/users", "user/login/**", "/login*").permitAll() .antMatchers("/mypage").hasRole("USER") .antMatchers("/messages").hasRole("MANAGER") .antMatchers("/config").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("/login_proc") .defaultSuccessUrl("/") .authenticationDetailsSource(authenticationDetailsSource) .successHandler(customAuthenticationSuccessHandler) .failureHandler(customAuthenticationFailureHandler) .permitAll(); http.exceptionHandling() .accessDeniedHandler(accessDeniedHandler()) .and() .addFilterBefore(ajaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class); } @Bean public AccessDeniedHandler accessDeniedHandler() { CustomAccessDeniedHandler accessDeniedHandler = new CustomAccessDeniedHandler(); accessDeniedHandler.setErrorPage("/denied"); return accessDeniedHandler; } @Bean public AjaxLoginProcessingFilter ajaxLoginProcessingFilter() { AjaxLoginProcessingFilter ajaxLoginProcessingFilter = new AjaxLoginProcessingFilter(); return ajaxLoginProcessingFilter; } } [AjaxLoginProcessingFilter] 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 org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; 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.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class AjaxLoginProcessingFilter extends AbstractAuthenticationProcessingFilter { private ObjectMapper objectMapper = new ObjectMapper(); public AjaxLoginProcessingFilter() { super(new AntPathRequestMatcher("/api/login")); } @Override public void setAuthenticationManager(AuthenticationManager authenticationManager) { super.setAuthenticationManager(authenticationManager); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException { if(!isAjax(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 IllegalStateException("Username or Password is empty"); } AjaxAuthenticationToken ajaxAuthenticationToken = new AjaxAuthenticationToken( accountDto.getUsername(), accountDto.getPassword() ); return getAuthenticationManager().authenticate(ajaxAuthenticationToken); } private boolean isAjax(HttpServletRequest request) { if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { return true; } return false; } } [AjaxAuthenticationToken.java] package io.security.corespringsecurity.security.token; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityCoreVersion; import javax.security.auth.Subject; import java.util.Collection; public class AjaxAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; private final Object principal; private Object credentials; public AjaxAuthenticationToken(Object principal, Object credentials) { super(null); this.principal = principal; this.credentials = credentials; setAuthenticated(false); } public AjaxAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) { super(authorities); this.principal = principal; this.credentials = credentials; setAuthenticated(true); } public Object getCredentials() { return this.credentials; } public Object getPrincipal() { return this.principal; } public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { if(isAuthenticated) { throw new IllegalArgumentException( "Cannot set this token to trusted - user constructor which takes a GrantedAuthority list instead" ); } super.setAuthenticated(false); } @Override public void eraseCredentials() { super.eraseCredentials(); credentials = null; } } [에러로그] Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2022-01-19 17:55:47.000 ERROR 7200 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:156) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at io.security.corespringsecurity.CoreSpringSecurityApplication.main(CoreSpringSecurityApplication.java:15) [classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_251] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_251] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_251] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_251] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.2.1.RELEASE.jar:2.2.1.RELEASE] Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:88) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:438) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:191) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:180) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] ... 13 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ajaxLoginProcessingFilter' defined in class path resource [io/security/corespringsecurity/security/configs/SecurityConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: authenticationManager must be specified at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1803) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:211) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:174) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:169) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:154) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:86) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:253) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:227) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5135) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_251] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) ~[na:1.8.0_251] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_251] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) ~[na:1.8.0_251] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.apache.catalina.startup.Tomcat.start(Tomcat.java:459) ~[tomcat-embed-core-9.0.27.jar:9.0.27] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:107) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE] ... 18 common frames omitted Caused by: java.lang.IllegalArgumentException: authenticationManager must be specified at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.afterPropertiesSet(AbstractAuthenticationProcessingFilter.java:164) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1862) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE] ... 56 common frames omitted
- 미해결스프링 시큐리티
소스코드
static에 있는 소스코드들은 어디서 얻나요..?
- 미해결스프링 시큐리티
질문있습니다
세션관리하는걸 예를 들어서 세션관리를 메모리가 아닌 레디스로 바꾸려면 전부 오버라이딩에서 재선언을 해줘야되는지 궁금합니다
- 미해결스프링 시큐리티
RoleHierarchy 데이터 포맷
안녕하세요 SetupDataLoader 소스에 응용해서 서비스 시작할 때 RoleHierarchy 데이터를 삽입하고 싶은데요. 방법을 찾아봐도 어떻게 해야 할지 몰라서 질문드리게 되었습니다.. RoleHierarchy 해당 포맷에 맞춰서 데이터를 삽입하려면 어떻게 해야 할지 알 수 있을까요.? 데이터 포맷 때문에 여쭤봐서 부끄럽지만. 방법을 어떻게 찾아봐야 할지 모르겠습니다. Set<RoleHierarchy> roleHierarchy = new HashSet<>(); parentName 필드 데이터 포맷은 어떻게 만들여야하는지 힌트를 얻을 수 있을까요..? private void setupSecurityResources() { //roleHierarchy 권한 삽입 Set<RoleHierarchy> roleHierarchy = new HashSet<>(); roleHierarchy.add("ROLE_ADMIN"); roleHierarchyRepository.save(new RoleHierarchy("ROLE_MANAGER",roleHierarchy));
- 미해결스프링 시큐리티
결론적인 개념 '익명사용자'
위에 질문 내용을 쭉봤지만 제가 생각하는 결론입니다.. 1. S.C으로 인증이 안된 모든 사용자는 익명사용자 2. 단순히 User가 Null로 처리해도 무방하지만 스프링 시큐리티를 사용하여 통일화하기 위해 사용 ex) 해당 코드내에 isAnonymouse() 와 isAuthenticated() 3. 다른 구조로 생각하면 로그인페이지도 익명사용자는 허용하게끔 처리하여 보여지게끔 처리 - 너무 깊게 생각하지않고, 인증이 안된 나머지 사용자라고 생각하고 있습니다
- 미해결스프링 시큐리티
URL방식 - Map기반 DB연동 강의
안녕하세요 URL 방식의 Map기반 DB 연동 관련되어서 공부를 진행하고 있습니다. 웹 기반 인가처리 DB 연동 - FilterInvocationSecurityMet (2) 강의부터는 JPA 설정 또는 gitgub 소스를 보고 최대한 참고해서 문제를 해결해보려고했지만, 강의내용 외 skip된 내용들이 생기면서 문제가 발생하고있습니다. 어떤 문제 때문인지 원인을 찾을 수 있을까요? 도움 부탁드립니다. 소스 : https://github.com/choiminjong/corespringsecurity/tree/v2 오류
- 미해결스프링 시큐리티
AppConfig 빈등록
안녕하세요 수동으로 AppConfig 파일을 생성 후 bean을 등록한 이유가 왜인지 혹 시 알 수 있을까요..? 흐름 이해가 어려운것 같습니다.. @Configurationpublic class AppConfig { @Bean public SecurityResourceService securityResourceService(ResourcesRepository resourcesRepository){ SecurityResourceService securityResourceService = new SecurityResourceService(resourcesRepository); return securityResourceService; }}
- 미해결스프링 시큐리티
안녕하세요 강사님 필터 사용 상황에 있어 질문 드립니다
스프링 시큐리티의 필터는 디스패처 서블릿에 도착전 요청을 처리 하거나, 디스패처 서블릿으로 부터의 응답을 처리하는데 사용이 되는데요. 디스패처 서블릿 에서 스프링 빈에 접근시에 처리를 할 수있는 인터셉터가 존재하는데요 이 둘은 어떨때 사용하는게 적절한지 모르겠습니다. 큰 차이가 없는거같기도 하구요... 차이점이나 각각의 적합한 사용 상황이 궁금합니다. 요약 - 필터를 쓰기 적합한 상황 - 인터셉트를 쓰기 적합한 상황 감사합니다
- 미해결스프링 시큐리티
정적 파일들이 ignore 되지 않는 문제가 발생합니다..
이번 강의에서 web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations()); 코드가 존재함에도 static 파일들이 ignore 되지 않는 문제가 발생합니다. 깃 파일과 비교하고, 강의 다시 보며 체크해봤는데도 도무지 원인을 찾지 못하겠습니다. 찾아주시면 정말 감사하겠습니다. 소스는 https://github.com/aittaa/corespringsecurity-authorize 입니다.
- 미해결스프링 시큐리티
궁금한 점이있습니다.
안녕하세요 강사님 이번 강의를 보면서 한 가지 궁금한점 생겼습니다. 커스텀하다가 궁금하여 질문드립니다. [요구사항 ] 사용자는 등록된 IP인경우 접근이 가능하다 사용자는 해당 권한 계층 상위 또는 해당 계층인 경우 접근이 가능하다. 사용자는 해당 부서계층에 상위 또는 해당 계층인경우 접근이 가능하다. [사용자 권한 ] ADMIN > MANAGER > USER [팀 권한] 영업팀 > 1팀 위와 같이 권한 뿐만아닌 부서에 대한 정보까지 탐색해야한다면 어떻게 해야할지에 대해 문의드립니다. [설계] 1. IP vote 같은 경우 ip가 존재한다면 ACCESS_ABSTAIN 보류 상태로 다음 vote를 체크하도록합니다. (강의와 동일) 2. 사용자 권한 - 사용자 계층은 해당 계층 또는 상위 계층이면 ACCESS_ABSTAIN 로 보류해야한다. - 기본으로 제공하는 RoleVoter를 통해 승인 여부를 결정하는데 해당 결정 방법은 보류가 아닌 승인이기 때문에 재정의해서 보류로 변경한다. 2-1. 기존 RoleHierarchyVoter 를 상속한 CustomRoleHierarchVoter 를 생성한다 - vote 메소스를 재정의하여 ACCESS_ABSTAIN 처리 함으로써 사용자권한에 대한 부분에대한 문제점--------------------------------------------- 3. RoleHierarchyVoter 를 상속한 GroupVoter 를 하나 생성해서 vote 메소드를 재정의해서 그룹에 대한 심사를 결정하고자합니다. 강의 기준에서 Group에대한 정보를 FilterSeuicrityInterceptor 에서 가져오게 하기 위해 SecurityInitializer 를 이용 데이터를 맵핑하고 빈을 설정했습니다. 4. 하지만 내부적으로 동작시 FilterSecurityInterceptor는 최초에 한번 해당 정보를 가져오는 과정을 진행하고AbstractSecurityInterceptor 에서 호출시에는 사용자의 권한정보만을 AccessDesisionManager에게 decide 하게 되는데요 결론적으로는 GroupVoter 에서는 권한정보가 사용자 정보를 가지고있어서 원하는 방향성으로 동작하지 않았습니다. 5. 이 경우 생각해볼 방향성이 provider 시점에 유저에 대한 정보를 조회 후 해당 정보중 그룹 정보도 같이 조회하여 WebAuthenticationDetails 에 그룹 정보를 포함하는 방법도 6. AffirmativeBased 클래스를 재정의하여 해당 GroupVoter를 호출할 때 configAttributes 에 대한 db 정보를 가져오는방법 (역할이 변질되는 느낌이 있어보입니다.) 7. FilterSecurityInterceptor 에서 AbstractSecurityIntercepter에서 beforeInvocation 부분을 재정의 하는 방법 이 있을 것 같습니다. 8. 만약 Groupvoter 정보를 캐싱하고자 한다면 어느시점이 좋을까요. [코드] 시큐리티 설정 코드 private List<AccessDecisionVoter<?>> getAccessDecisionVoters() { List<AccessDecisionVoter<? extends Object>> accessDecisionVoters = new ArrayList<>(); accessDecisionVoters.add(accessIp()); accessDecisionVoters.add(roleVoter()); accessDecisionVoters.add(groupVoter()); return accessDecisionVoters;}@Beanpublic AccessDecisionVoter<? extends Object> accessIp() { return new IpAddressVoter(securityResourceService);}@Beanpublic AccessDecisionVoter<? extends Object> roleVoter() { return new CustomRoleHierarchyVoter(roleHierarchy());}@Beanpublic RoleHierarchy roleHierarchy() { return new RoleHierarchyImpl();}@Beanpublic AccessDecisionVoter<? extends Object> groupVoter() { return new GroupVoter(roleGroupHierarchy());}@Beanpublic RoleHierarchy roleGroupHierarchy() { return new RoleHierarchyImpl();} CustomRoleHierarchyVoter - 기존 RoleVoter에서 승인 처리되는 부분을 보류 상태로 변경했습니다. public class CustomRoleHierarchyVoter extends RoleHierarchyVoter { public CustomRoleHierarchyVoter(RoleHierarchy roleHierarchy) { super(roleHierarchy); } @Override public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { if (authentication == null) { return ACCESS_DENIED; } Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication); for (ConfigAttribute attribute : attributes) { if (this.supports(attribute)) { // Attempt to find a matching granted authority for (GrantedAuthority authority : authorities) { if (attribute.getAttribute().equals(authority.getAuthority())) { return ACCESS_ABSTAIN; } } } } return ACCESS_DENIED; } Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) { return authentication.getAuthorities(); }} GroupVoter - 그룹 정보에 따른 승인 처리 부분입니다. 해당 부분에서 그냥 DB 정보를 가져와서 Map에다가 저장해서 처리해볼까 하는 생각도 있는데 확실치가 않네요 .. public class GroupVoter extends RoleHierarchyVoter { public GroupVoter(RoleHierarchy roleHierarchy) { super(roleHierarchy); } @Override public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { // 미구현 return result; }}
- 미해결스프링 시큐리티
URL 접근시 "Method Not Allowed" 오류 발생
안녕하세요 원인을 찾아보려고했지만 결국 찾지못해서 댓글을 남기게되었습니다. 사용자 계정의 권한이 있지만 POST으로 "/api/messages" 전송했을때 "error": "Method Not Allowed", 오류가 발생합니다. 권한이 있는데 오류가 발생합니다. 어떤 부분에서 오류가 발생하는지 조언을 받을 수 있을까요..? 강의내용 : 인증 및 인가 예외 처리 - AjaxLoginUrlAuthenticationEntryPoint, AjaxAccessDeniedHandler 소스 : https://github.com/choiminjong/corespringsecurity commits : 인증 및 인가 예외 처리 - AjaxLoginUrlAuthenticationEntryPoint, AjaxAccessDeni
- 미해결스프링 시큐리티
createSuccessAuthentication
createSuccessAuthentication에서 권한 정보까지 조회해서 토큰에 저장하신다고 하셨는데 여기서 권한이란게 서비스로직에서의 권한, 즉 member, admin 이런 권한이 아닌거 같은데 여기서 말하는 권한이 어떤것에 대한 권한인건가요??
- 미해결스프링 시큐리티
안녕하세요 강사님 강의에 나온 FilterChainProxy에 대해 질문이 있습니다.
추가 학습을 해 보았더니, 클라이언트로 부터 온 요청은 서블릿 필터가 받게 되고, 서블릿 필터가 처리할 수 없는? 요청은 DelegatingFilterProxy를 통해 스프링 Application Context에 등록된 필터 빈 으로 책임을 위임한다고 나와있는데요. 이때 FilterChainProxy가 서블릿 필터로 부터 DelegatingFilterProxy을 통해 역할을 위임받게 되는건가요? 그렇다면 FilterChainProxy가 위치한 곳은 Spring의 IoC컨테이너일텐데 어떻게 서블릿 컨테이너에 위치한 서블릿 필터가 스프링 컨테이너에 위치한 FilterChainProxy에 필터링 작업을 위임할 수 있게 되는지 궁금합니다.
- 미해결스프링 시큐리티
안녕하세요 강사님 강의 보던중 비밀번호 저장 관련 질문이 있습니다.
14분 30초 대에 security.user.name과 security.user.password를 application.properties파일에 저장을 해 주셨는데요. 이럴경우 노출이 되어서 좋지 않을텐데 현업에서는 어떤 방법으로 숨기는지 궁금합니다
- 미해결스프링 시큐리티
로그인 문제
안녕하세요. 디비에 데이터까지 잘 넣었고 로그인 부분도 손도 안댔는데 로그인을 하면 localhost:8080/error 페이지로 이동하게 됩니다.. 페이지 메시지는 {"timestamp":"2022-01-01T20:11:13.890+00:00","status":999,"error":"None"} 위와 같이 뜨구요... localhost:8080/ 으로 이동하면 로그인은 또 된 상태입니다. ide에서는 오류메시지도 안뱉고 디비에서 데이터 select도 잘 해오는것 같은데.. 다른 코드 비교해봐도 이유를 모르겠습니다.. ............. 질문하던 와중에 해결방안을 찾았습니다 /error 페이지를 permitALL 해주니 정상적으로 작동했습니다.. 혹시 다른 방안이 있을까요?
- 미해결스프링 시큐리티
세션 고정 보호
14:53초 세션 고정보호 설명과 관련해서 질문드립니다. 공격자가 서버에 접속해서 세션ID값을 받고 그 값을 사용자에게 심어놓는다고 하셨는데 어떻게 심어놓나요? 공격자가 만든 웹에 접근하게 하나요?
- 미해결스프링 시큐리티
클라이언트에서 csrf 토큰은 어디 저장된다고 봐야하나요?
세션아이디의 경우 클라이언트의 쿠키에 저장되는 반면 csrf토큰은 어디에 저장된다고 봐야 할까요 .?
- 미해결스프링 시큐리티
필터의 동작 시기 에 대해 질문드립니다 강사님!
먼저 RememberMeAuthenticationFilter 가 동작하기 위해 두가지 조건을 충족해야한 다고 이해 했는데요! 하나는 세션이 만료되었을때(세션영역에서 SC를 찾을수 없음)두번째는 사용자가 최초 인증때 RemeberMe를 체크 하여을때 입니다. 근데 5:34 쯤에 "리멤버미" 라는 토큰을 가지고 있는지에 따라 필터체인으로 이동할지 안할지가 결정되신다고 했는데 애초에 사용자가 리멤버미를 체크 안하면 RememberMeAuthenticationFilter 가 동작하지 않아 5:34초 쯤에 말씀하신 부분이 무의미 해지는것 같아 질문드립니다.