묻고 답해요
130만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링부트 시큐리티 & JWT 강의
27장 따라하는 중입니다. Controller를 안타는듯 합니다.
감이 잘 안와서 질문 올립니다. git@github.com:afgman4/jwt.git 27강 - jwt토큰 서버 구축완료 강의까지 다 봤는데.. 마지막 장에서 JwtAuthorizationFilter 에 디버깅을 걸고 해봤는데 중단점도 잘 걸리고.. principal에 값 세팅 잘되는 것도 확인이 되었습니다. @GetMapping("/api/v1/user")public String user(Authentication authentication){ PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal(); System.out.println(principalDetails.getUser()); return "user";} 부분에 중단점을 찍고 디버깅을 했는데 안타네요. /api/v1/user 로 하면 왜 body 에 1이라는 값이 박히는지 도통이해가 안갑니다. "user"라고 떠야 할거 같은데 말이죠..;; /api/v1/admin 하면 403 에러 잘 떠서 좋은데.. JwtAuthorizationFilter 에서 SecurityContext에 세팅을 하고 controller로 넘어와야 할거 같은데 안오는게 이상하네요 제 소스에 뭐가 잘못된게 있을까요?
-
미해결스프링 시큐리티
CustomAuthenticationProvider 질문입니다.
안녕하세요. 이번 강의를 들으면서 질문하고자 하는 내용은 바로 앞 강의 CustomUserDetailsService 구현만으로 로그인이 정상적으로 되는지 안 되는지 체크를 해 주었는데, 이번 강의에서는 CustomAuthenticationProvider 를 사용해서 입력 비밀번호와 디비 저장 비번을 matches 로 비교를 직접하셨는데요. 기능적으로 두 강의의 차이를 모르겠어요. 그럼 실제 사이트에서 로그인 로직을 만들때는 CustomUserDetailsService, CustomAuthenticationProvider 모두를 구현해 줘야 하는건가요? 감사합니다. ^.^
-
해결됨스프링 시큐리티
FactoryBean관련해서 질문이 있습니다.
강사님 안녕하세요. 매번 질문만 하게 되는데 답변 친절히 해주셔서 감사합니다 ㅠ 강의를 보면서 궁금한 점이 있었는데 우선 첫번째로, FactoryBean으로 Map객체를 구현하는 이유가 있을까요? 만약 저에게 구현해보라고 한다면, UrlFilterInvocationSecurityMetadataSource에서 데이터들을 가져와서 한번에 했을 것 같은데.. 뭐 이런식으로.. FactoryBean으로 구현하신 이유는 DefaultFilterInvocationSecurityMetadataSource와 최대한 비슷하게 구현하기 위해서 그렇게 하신건가요? 두번째로, UrlResourceMapFactoryBean에서 if (resourceMap == null ) { init( ) }이라고 하셨는데, 이렇게 하신 이유가 무엇때문에 그런건가요? resourceMap은 호출때마다 DB에서 불러와야 하는 것 아닌가요? 항상 감사합니다 ..
-
해결됨스프링 시큐리티
런타임 중, 메소드 인가 맵 등록시, 서비스 Proxy 가 만들어지지 않는 이유의 질문입니다.
좋은강의 감사드립니다. 약간 다른 시도를 해보고 잘 안풀리게되어 질문을 남기게 되었어요.메소드 권한 부여는 반드시 MapBasedMethodSecurityMetadataSource 생성자를 통해서만 등록이 가능할까요? 초기화가 끝난 이후 런타임에서 addSecureMethod(string, configAttrList) 를 통해 등록하면 프록시 생성이 안되는것 같더라구요.. 그래서 아래와 같은 시도가 있었습니다. 저는 MapBasedMethodSecurityMetadataSource 를 extends 하여 CustomMapBasedMethodSecurityMetadataSource 를 만들어, 생성이 된 이후, 메소드 리소스맵 등록을 super.addSecureMethod() 메서드로 하려는 시도를 했습니다. 이후 @EventListener(ContextRefreshedEvent.class) 이벤트 핸들러를 MethodSecurityConfig 에 작성하고, 이벤트 발생 시점에 App컨택스트로 부터 CustomMapBasedMethodSecurityMetadataSource 를 가져와 reload() 를 호출하여 Map 을 통해 메서드 정보 등록이 되도록 구성했습니다 문제는서버 기동 및 컨트롤러 호출 후, Method Resource 가 등록 과정에 서비스 프록시 가 생성되지 않아 서비스 메서드 가 그대로 호출이 되었는데요, Debug 확인 결과 클래스 명 메소드명 Map 파싱은 문제가 없었습니다. 아래는 서버 기동 후, 커스텀 메소드 메타데이터 소스 를 메모리에서 조회 결과입니다. 위의 과정으로반드시 생성자를 통해 Map 을 전달 해야만 Proxy 생성이 되는것으로 판단되었습니다이벤트 리스너를 통해 methodMap 등록을 지연하게 되면 필터링 처리가 안되는 이유가 궁금한데요..이런 부분에 대해 조언을 구합니다. 아래는 작성한 Method..Config 와 Method...Source 입니다 MethodSecurityConfig public class MethodSecurityConfig { ... /** * DB 초기화 직후, METHOD 인가정보 등록 */ @EventListener(ContextRefreshedEvent.class) @Transactional public void onContextRefreshed(ContextRefreshedEvent event) { ApplicationContext ctx = event.getApplicationContext(); var customMapBasedMethodSecurityMetadataSource = ctx.getBean(CustomMapBasedMethodSecurityMetadataSource.class); customMapBasedMethodSecurityMetadataSource.reload(); } ...} CustomMapBasedMethodSecurityMetadataSource public class CustomMapBasedMethodSecurityMetadataSource extends MapBasedMethodSecurityMetadataSource { private final MethodResourceMapFactoryBean methodResourceMapFactoryBean; public CustomMapBasedMethodSecurityMetadataSource(MethodResourceMapFactoryBean methodResourceMapFactoryBean) { /* 생성자를 통해 methodMap 전달시 작동 */// super(Map.of(// "io.security.corespringsecurity.aopsecurity_test.AopMethodAuthTestService.methodSecured",// List.of(new SecurityConfig("ROLE_USER"))// )); this.methodResourceMapFactoryBean = methodResourceMapFactoryBean; } /** * DB 데이터 초기와 직전 로딩 이슈로, DB 초기화 이후 값을 가져오기위한 리로딩 메서드 */ public void reload() { LinkedHashMap<String, List<ConfigAttribute>> resourceMap = methodResourceMapFactoryBean.getObject(); for (Map.Entry<String, List<ConfigAttribute>> resourceEntry : resourceMap.entrySet()) { String fullPackageClassMethodName = resourceEntry.getKey(); List<ConfigAttribute> configAttributes = resourceEntry.getValue(); addSecureMethod(fullPackageClassMethodName, configAttributes); } } /** * 보안 메서드에 대한 설정을 추가합니다. 메서드 이름은 여러 메서드를 등록하기 위해 `*` 로 끝나거나 시작할 수 있습니다.<br /> * 풀패키지 클래스명 + 메서드명 파싱 및 S.Security 에 메서드 정보 추가 <br /> * Key: 풀패키지 클래스명 + 메서드명(ex: "a.b.Class.*method or method*") <br /> * Value: ConfigAttribute List <br /> * 참고: super 클래스 private addSecureMethod(name, attr) 메소드 복제 */ private void addSecureMethod(String name, List<ConfigAttribute> attr) { int lastDotIndex = name.lastIndexOf("."); Assert.isTrue(lastDotIndex != -1, () -> "'" + name + "' is not a valid method name: format is FQN.methodName"); String methodName = name.substring(lastDotIndex + 1); Assert.hasText(methodName, () -> "Method not found for '" + name + "'"); String typeName = name.substring(0, lastDotIndex); Class<?> type = ClassUtils.resolveClassName(typeName, ClassUtils.getDefaultClassLoader()); super.addSecureMethod(type, methodName, attr); } } 읽어주셔서 감사합니다.
-
해결됨스프링 시큐리티
UsernamePasswordAuthenticationToken
안녕하세요 강사님, 뜬금없는 질문이 될 수 있지만 그래도 궁금한 것은 여쭤보고 싶어 질문 합니다. CustomAuthenticationProvider가 사용하고자 하는 토큰 이름이 UsernamePasswordAuthenticationToken이라는 것은 외워야(기억해야) 하는 것인가요? 만약에 토큰 이름이 기억 안나면 어떻게 해야 하나요? 실제 프로젝트에서 개발할 때 이 흐름과 (클래스, 토큰등의) 이름 정도는 머리속에 다 있어야 하는 것인지 궁금합니다.
-
해결됨스프링 시큐리티
chapter3 소스코드
안녕하세요 소스코드 관련해서 질문드립니다. chapter3 소스코드는 브랜치에 없는 것 같은데요. 다른 수강생분들은 어떻게 실습 하신 건지 알 수 있을까요? 따로 타이핑쳐서 공부하는 것은 당연한 것이지만 기본 소스가 없어서 어떻게 해야하는 지 답답하네요. chap4는 templates 밑에 구조가 다른 것 같더라구요. 강사님, chapter3소스 지금이라도 새로운 프로젝트로 제공해주실 수는 없으신가요?
-
미해결스프링 시큐리티
서버 기동 후 루트 접근 시 `/` AccessDeniedException 질문입니다
예제에서는 DB 리소스 설정 이후에도루트접근이 가능해 보이는데, 저의경우는 접근이 불가능합니다 아래 이미지는 서버 기동 직후, 브라우저를 통해 루트 접근시차단이 되는 부분에 BreakPoint 를 잡아 캡쳐했습니다. 익명 사용자의 경우에 허용되어야 할 `/` 웹 루트 경로가Denied 되는 것은 어느 부분이 문제일까요.. DB 연동은 잘 처리가 되었으나 이부분에서 막힙니다.특별히 설정을 바꾼것이 없는데DB 연동 처리 이후, 계속 여기서 부터 막힙니다.어느 부분부터 살펴봐야 해결이 될까요..? 혹시 정상인가요?( 지난 강의 돌려보다가 문뜩 생각이 듭니다) 혹제 제가 놓친부분에 대해 조언을 구합니다.읽어주셔서 감사드립니다.
-
해결됨스프링 시큐리티
RequestCache 가 있는 상태에서 뒤로가기 문제
안녕하세요, 강의 너무너무 재밌게 듣고 있는 수강자입니다 :) 오늘 인증 성공 핸들러 강의 듣다가 몇가지 테스트를 해봤는데, 정말 난감한 상황을 마주쳤습니다. 어떤 사용자가 아래처럼 행동한다고 가정하겠습니다. 1. 메인페이지( = "/" ) -> 마이페이지 메뉴 클릭 2. 로그인 화면 뜸 (이때 세션에 RequestCache 가 생성) 3. 뒤로가기 4. 화면 상단의 로그인 버튼 클릭 5. 로그인 화면 뜸 (여전히 세션이 2번의 RequestCache 를 간직함) 6. 로그인을 성공 7. 마이페이지로 이동 이럴 때는 어떻게 해야할지 정말 난감하네요. 그냥 로그인 버튼을 클릭해서 로그인에 성공했으니, 로그인 성공 디폴트 경로인 "/" 로 보내고 싶습니다. 어떻게 하는게 좋을까요?
-
미해결스프링 시큐리티
디버깅 방법
안녕하세요. 잘 듣고 있습니다. 현재 제가 사용하는 인텔리J에서는 WebSecurityConfigureAdapter.java 디버깅이 안되는데.. (찾아보니 외부 Jar 파일을 디버깅하려면 remote 디버깅을 해야한다는데 이방법으로 하신건가요? ) 인텔리J에서 어떤식으로 설정을 해야 강사님이 하는 것과 같이 디버깅이 되는건가요?
-
해결됨스프링 시큐리티
`익명 사용자` 개념에 대한 질문
`익명 사용자` 라는 것이 그냥 보기에는 접속이 가능한 것처럼 보였지만, 강의와 여러 QnA 를 다시 보다알게된 결론으로 정리를 해보았습니다. Spring Security 에서의 `익명사용자` 개념 정리 인증이 되기 전이나, 이후 의 사용자 모두유효한 인증토큰을 갖고있지 못하면 `익명 사용자`이다 `익명 사용자`는 로그인이 가능한 경로를 통해 인증허가를 을 받게 될 경우, 일반 사용자로 등극하여, 로그인 접속 및 향후 접속유지가 가능하게된다. 인증을 받지 못한 사용자는 `익명 사용자`로 분류되어, `익명 사용자` 인증 토큰이(인증 객체) 익명 사용자 관리 명목으로 생성되지만, 로그인과 관련된 접근 권한은 없다(세션 생성이 되지않음) -> `redirect /login page` `익명 사용자` 전용으로 발급된 인증토큰을 통해, 향후 `익명 사용자` 접근 여부를 관리 할 수 있다 틀린 부분이 있다면 조언을 구합니다. 감사합니다.
-
미해결스프링 시큐리티
UrlResourcesMapFactoryBean을 FactoryBean인터페이스를 상속해서 만드신 이유가 있나요?
저는 FactoryBean인터페이스를 상속하지 않고 @Component로 등록해서, 내부에 resourceMap을 반환하는 메소드를 하나 만들면 된다고 생각했습니다. FactoryBean을 상속받으면 어떠한 장점이 있어서 구현하신건지 궁금합니다
-
해결됨스프링 시큐리티
RememberMe 설정 시 문제가 발생합니다...
제가 RememberMe 설정 중 문제가 발생하여 해당 부분이 잘 안풀려 강사님께 질문 드립니다. 로그인 한 사용자 정보가 필요하여 AuthenticationProvider 에서 하단 캡쳐화면 처럼 설정을 하였습니다. 그리고 RememberMe 기능을 하단 캡쳐 화면 처럼 설정 하였습니다. 설정 후 rememberMe 기능 사용 시 로그인이 안되는 문제가 발생을 하였습니다. 그래서 디버깅 하여 확인 시 하단 캡쳐 화면과 같이 해당 부분에서 (TokenBasedRememberMeService에서 UserDetails user = getUserDetailsService().loadUserByUsername(username);) 다시 사용자를 다시 조회를 하여, email 파라미터의 값이 객체가 들어와서 로그인이 안되는 문제가 발생 합니다. 제가 RememberMe 기능 과 @AuthenticationPrincipal 어노테이션을 이용해서 Dto의 사용자 정보를 둘 다 사용을 하고 싶은데 이 경우 어떻게 해야하는지 구글링을 봐도 안나와서 강사님께 여쭤봅니다. 좋은 강의 해주셔서 감사합니다.
-
미해결스프링 시큐리티
PSQLExeption 오류 나는데요 ?
처음 설치하면서 계정 생성하고 암호 입력하면 자동으로 db 생성 되지 않나요 ? 계정 ,비번 문제도 아닌거 같고, 폰트가 깨지는 거 보니 인코딩 문제일 수도 있겠는데 ...? 검색해도 안나오네요 ㅠ Postgres는 최신형입니다. -------------------------------------------------------- org.postgresql.util.PSQLException: Ä¡¸íÀû¿À·ù: "springboot" µ¥ÀÌÅͺ£À̽º ¾øÀ½ (pgjdbc: autodetected server-encoding to be ISO-8859-1, if the message is not readable, please check database logs and/or host, port, dbname, user, password, pg_hba.conf) at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2497) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2618) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:135) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:250) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.Driver.makeConnection(Driver.java:458) ~[postgresql-42.2.8.jar:42.2.8] at org.postgresql.Driver.connect(Driver.java:260) ~[postgresql-42.2.8.jar:42.2.8] at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-3.4.1.jar:na] at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:353) ~[HikariCP-3.4.1.jar:na] at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) ~[HikariCP-3.4.1.jar:na] at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473) ~[HikariCP-3.4.1.jar:na] at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:562) ~[HikariCP-3.4.1.jar:na] at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-3.4.1.jar:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-3.4.1.jar:na]
-
미해결스프링 시큐리티
ConcurrentSessionControlAuthenticationStrategy 질문입니다!
현재 Ajax 방식 로그인을 위해 해당 강의에서 나온 방식으로 AbstractAuthenticationProcessingFilter를 상속받아 Filter를 커스텀하여 로그인 기능이 구현되어있습니다. 이후 동시세션 제어를 위해 securityConfig에서 아래 코드를 적용하였지만 http .sessionManagement() .maximumSessions(1); AuthenticationProcessingFilter를 커스텀하여 ConcurrentSessionControlAuthenticationStrategy이 적용되지 않는것 같은데 적용하는 방법을 알 수 있을까요?!
-
해결됨스프링 시큐리티
RoleHierarchy 엔티티를 따로 만들지 않아도 되나요?
RolehierarchyImpl 에 String 타입 프로퍼티에 A > B\n 이런 타입으로 지정만 해주면 될 것 같아서 Role 엔티티 자체에 RoleGrade 라는 ENUM 타입을 지정해줘서 알파벳 순으로 가져와서 그걸 for-loop 돌리면서 문자열만 만들면 될거 같아서 해봤는데 실시간으로 적용이 되더라구요. @Overridepublic void reloadRoleHierarchy() { StringBuilder sb = new StringBuilder(); List<Role> allRoles = roleRepository.findAllWithRoleGrade(); for (int i = 0; i < allRoles.size(); i++) { try { allRoles.get(i + 1); /* 검증 코드 */ sb.append(allRoles.get(i).getRoleName()); sb.append(" > "); sb.append(allRoles.get(i + 1).getRoleName()); sb.append("\n"); } catch (Exception e) { break; } } this.roleHierarchy.setHierarchy(sb.toString());} ResourcesController 에서 자원 등록, 삭제 하고나서 reload 메소드를 호출했듯이 이 메소드를 Role 등록, 삭제 뒤에 등록해주니 잘 되네요. 혹시 실무에서는 이런식으로 쓰는것보다 엔티티를 따로 만들어서 관리하는것을 선호하나요? RoleHierarchy 엔티티 안에 자기 자신을 ManyToOne 으로 조인하니 너무 어려워서 이렇게 해보긴 했는데, 실무에서는 엔티티 방식으로 관리하는걸 선호하는지 궁금해서 질문드립니다. 혹시 몰라 git 링크 첨부해봅니다. 한번 봐주시면 감사하겠습니다. review4 브랜치입니다. https://github.com/twosom/SpringSecurity-ProjectReview.git *추가적으로 이제 계층 구조 Role을 구성했으면 Resources 랑 Role 은 굳이 N : N 관계로 구성하지 않아도(테이블 상에서는 1 : N , N : 1) 되는건가요? 기존에는 하나의 Reosurces 에 여러개의 Role 이 있을 수 있고 Role 하나가 여러 Resources 에 포함될 수 있기에 N : N 관계로 만들었지만, 계층 구조가 적용되면 외래키가 Resources 테이블에만 존재해도 (N : 1) 될 것 같아서요. 항상 좋은 강의 감사드립니다.
-
미해결스프링 시큐리티
그럼 SecurityContext가 저장되는 곳은 총 3곳인건가요?
처음에 Authentication객체를 SecurityContext에 담아서 보관한다는것 까지능 이해했습니다. 그럼 SecurityContext가 저장되는 곳이 1. ThreadLocal 2. HttpSession 3. SecurityContextHolder 총 3개의 공간에 저장되는 건가요? 그리고 이 공간은 각각 독립된 공간인건가요? 아니면 ThreadLocal안에 SecurityContextHolder가 포함되고 HttpSession은 따로 저장되는 구조인건가요? 궁금합니다.
-
미해결스프링 시큐리티
안녕하세요
혹시 최종 완성본 말고 이 강의까지 완성된 건 없는건가요??? 어떤 클래스가 새로 생긴거고 어떤 클래스를 고쳐야 할지 완성본을 갖고 판단 할 수 가없습니다. 따라 치면서 공부 하고싶은데 도저히 다음 강의를 진행 할 수 가 없습니다..
-
미해결스프링 시큐리티
안녕하세요. 현재 로그인한 사용자 정보 가져오는것에 대한 질문입니다.
@GetMapping("/mypage")public String myPage(Model model, Authentication authentication) throws Exception { AccountContext ac = (AccountContext) authentication.getPrincipal(); model.addAttribute("info", ac.getUsername()); return "user/mypage";}바로 전 강의에서는 이 코드가 정상적으로 실행 됐는데,이번 강의에서 추가적인 작업을 한 뒤에는 error page가 나옵니다.. 혹시 이유와 어떻게 고쳐야하는지 알 수 있을까요???
-
해결됨스프링 시큐리티
Ajax 인증 관련 궁금한게 있습니다.
굳이 Ajax로 인증을 해야되나 싶은 생각이 들었는데아래 생각이 맞을까요?프론트를 타임리프, jsp 등을 이용했을 때는 인증, 인가를 Form 형식으로 구현하고프론트를 React, Vue 와 같은 웹 클라이언트로 구성했을 때는인증, 인가를 Ajax 형식으로 구현해서 사용하는건가요?
-
해결됨스프링 시큐리티
defaultSuccessUrl과 failureUrl의 작동방식 차이?
.defaultSuccessUrl("/success", true) .failureUrl("/fail") 직접 따라해보다가 defaultSuccessUrl 메서드의 두번째 인자의 true를 꼭 넘겨줘야 login이 성공했을 때 /success url로 이동하는 것을 알게 되었는데요. .defaultSuccessUrl("/success")처럼 두번째 인자 없이 쓰는 경우는 어떤 경우인가요? .failureUrl은 왜 두번째 인자가 필요 없는건가요?