부트말고 스프링프레임워크에서 시큐리티 기능을 이용한 회원별 권한 부여된 게시판 기능을 만들려고 하는데 SPRING MVC02와 03, 04 를 한 프로젝트 안에 다 작업해도될까요?? 필요한 기능이 관리자 - 글쓰기(사진 멀티업로드) 이용자 - 조회, 찜기능 비회원- 조회 이런것들입니다. 시큐리티 기능을 활용해서 사이트를 만들어보려고 하는데 어떤 챕터를 활용하면 좋을지 의견 부탁드립니다..! 기존 세팅은 되어 있어서 MVC01 은 제외하고 작업하면 될 것 같은데 이렇게 되면 MVC02부터 실행해도 괜찮은지도 말씀 부탁드립니다..! 감사합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 안녕하세요. 강의 잘 듣고 있습니다.강의 도중 궁금한 점이 생겨 질문드립니다. 강의에서는 POST나 PUT요청에서도 Response DTO 객체를 생성해서 전달하셨는데, 실제 실무에서도 이렇게 하는지 궁금합니다. 질문드린 이유는 HTTP Response code상 201이나 204 등의 응답코드가 있는 것으로 알고있는데, Response를 매번 생성하는게 실질적으로 좋은 설계이기 때문인지, 아니면 변경이 완료된 것을 실제로 조회하면서 이해를 돕기 위함인지 궁금했습니다. 감사합니다.
MVC06 소스 톰캣 실행 시 아래 오류가 발생합니다. ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberController': Unsatisfied dependency expressed through field 'memberUserDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ' kr.ody.apps.security .MemberUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject( AutowiredAnnotationBeanPostProcessor.java:586 ) at org.springframework.beans.factory.annotation.InjectionMetadata.inject( InjectionMetadata.java:91 ) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues( AutowiredAnnotationBeanPostProcessor.java:372 ) at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.populateBean( AbstractAutowireCapableBeanFactory.java:1344 ) at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.doCreateBean( AbstractAutowireCapableBeanFactory.java:582 ) at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.createBean( AbstractAutowireCapableBeanFactory.java:502 ) 구글링으로 파악이 안되네요. 원인이 무엇일까요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네 [질문 내용] 안녕하세요, localhost:8080/members/new에 접근하면 whitelabel에러가 떠서 이유가 무엇인지 질문 드립니다. 오타같은 것도 없고 구조도 정확한 것 같은데 어떤 부분이 문제인건지 전혀 모르겠습니다... hello.hellospring/controller/HomeController hello.hellospring/controller/MemberController resources/templates/home.html resources/templates/members/createMemberForm.html 폴더 구조 실행 결과
안녕하세요! 최근 스프링 시큐리티가 패치되면서, 기존 메서드 체이닝 방식이 아닌 람다식을 통해 함수형으로 설정하도록 바뀌었는데요. 다른 설정 부분은 새롭게 바뀐 방식을 찾았으나.... 아래 사진의 마지막 apply() 는 도저히 찾을 수가 없더라고요...ㅠ 혹시 아시는 분계실까요? ('apply(C)' is deprecated since version 6.2 and marked for removal )
우선 좋은 강의 감사드립니다. 강의내용중 running -> runnable 로 이동하는 방법에 yield, I/O 가 있다고 하셨는데, DB query 등을 하면 응답이 올때까지 waiting으로 상태변경이 되는게 아닐까 싶어 샘플코드를 짜보니 정말로 running-> runnable 상태이던데, 1) 응답이 올때까지 기다리는 것이기도 하고 2) runnable 이면 언제라도 running이 될수 있는데, 이 경우 running -> runnable -> running 으로 상태변경되었는데 아직 응답이 오지 않았으면 다시 runnable 로 넘어가고.. 이런게 반복되는건가요? 샘플코드는 아래와 같이 만들어봤습니다. RestTemplate template = new RestTemplate(); template.getEntity(xxx); // 응답이 10초 걸리는 api 호출 10초 내에 위 작업을 하는 쓰레드의 상태를 log 로 찍으니 runnable 로 나왔습니다.
안녕하세요, 우선 좋은 내용의 강의 감사드립니다. 이어 Spring Security 계층 권한 설정 방법에 대해 아래와 같이 몇 가지 질문을 드리고자합니다. [질문 항목] DB를 사용해서 계층 권한 테이블 을 선언하고 부모, 자식 관계의 권한 데이터(row)를 등록해 놓은 상황에서 프로그램을 실행시키게 되면 현재 이 계층 권한 테이블에 있는 데이터에 한해서만 Security 권할 설정이 이루어지는 것인가요? 만약, 추후 DB에 직접 새로운 계층 권한 정보 가 등록된다면 해당 프로그램이 재시작 되어야만 변경된 계층 권한 정보가 동기화되는 것인가요? 1번 항목과 비슷한 맥락으로 한 회원이 서비스 이용중 자신의 권한이 사이트 관리자에 의해 변경되었다면 변경된 권한이 적용되는 시점에 대해서도 궁금합니다. Spring Security 기본 정책(?)상 계층 권한을 나타낼 때에는 문자열 형태로 권한 관계를 > 를 사용하여 표기하는 것을 볼 수 있었는데요. 이렇게 문자열 형태가 아닌 다른 형태(예를 들어 Map 등) 로도 표기가 가능한가요? 만약, 이런 설정 방법이 존재한다면 가이드를 제공해주실 수 있을까요? 아직 강의를 완강한 것이 아니기에 질문 내용이 부족한점 양해드리며, 미리 답변 감사드립니다.
호돌맨의 요절복통 개발쇼 시즌2 배포 준비(빌드) 강의를 듣고 있는데, 계속 오류가 생겨 질문 올립니다. 우선 ./gradlew clean으로 삭제한 뒤 ./gradlew build를 실행하면 이런 식으로 한글이 깨졌다는 에러가 나옵니다. 해결하고자 했던 방안 세팅 바꾸기 파일 인코딩 바꾸기 Help - EditCustom Vm Options 이런 방법을 써 봤으나 다 되지 않았고 이 코드를 build.gradle에 넣는 방식으로 해결했더니 build 후 libs 폴더가 생기지 않습니다. 그래서 이 부분을 true로 바꿔주면 plain snapshot만 생깁니다. 어떻게 해결해야 하나요? 밑 코드는 build.gradle 파일입니다. plugins { id 'java' id 'org.springframework.boot' version '2.5.9' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id "org.asciidoctor.jvm.convert" version "3.3.2" } group = 'com.reheat' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11' } configurations { compileOnly { extendsFrom annotationProcessor } asciidoctorExt } repositories { mavenCentral() } ext { asciidocVersion = "2.0.6.RELEASE" snippetsDir = file('build/generated-snippets') } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' testImplementation 'junit:junit:4.13.1' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //REST Docs asciidoctorExt "org.springframework.restdocs:spring-restdocs-asciidoctor:${asciidocVersion}" testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:${asciidocVersion}" } tasks.named('test') { useJUnitPlatform() } test { outputs.dir snippetsDir } asciidoctor { inputs.dir snippetsDir configurations 'asciidoctorExt' dependsOn test } bootJar { enabled = true dependsOn asciidoctor copy { from asciidoctor.outputDir into "src/main/resources/static/docs" } } jar{ enabled = true } tasks.withType(JavaCompile){ options.encoding = "UTF-8" }
안녕하세요 늘 좋은 강의 올려주셔서 감사합니다. authenticationManager 파라미터 전달 부분에서 문제가 있어 이렇게 게시글 남깁니다! 새로 올려주신 소스코드를 보며 새로 업데이트된 시큐리티에서 사용하기위해 authenticationManager 를 파라미터로 전달하는 부분을 적용하였습니다 그런데 Authentication authentication = authenticationManager.authenticate(authenticationToken); 부분에서 loadbyUsername() 함수를 호출하지 못하고 있습니다... JwtAuthenticationFilter // 유저네임 패스워드 토큰 생성 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( loginUser.getUsername(), loginUser.getPassword() ); System.out.println("JwtAuthenticationToken : 토큰생성완료"); // authenticate() 함수가 호출 되면 인증 프로바이더가 유저 디테일 서비스의 // loadUserByUsername(토큰의 첫번째 파라메터) 를 호출하고 // UserDetails를 리턴받아서 토큰의 두번째 파라메터(credential)과 // UserDetails(DB값)의 getPassword()함수로 비교해서 동일하면 // Authentication 객체를 만들어서 필터체인으로 리턴해준다. // Tip: 인증 프로바이더의 디폴트 서비스는 UserDetailsService 타입 // Tip: 인증 프로바이더의 디폴트 암호화 방식은 BCryptPasswordEncoder // 결론은 인증 프로바이더에게 알려줄 필요가 없음. Authentication authentication = authenticationManager.authenticate(authenticationToken); System.out.println("authentication : authentication 생성 완료"); PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal(); System.out.println("Authentication : " + principalDetails.getUser().getUsername()); return authentication; SecurityConfig @Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { private final CosConfig cosConfig; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); http.csrf(csrf -> csrf.disable()); http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); http.addFilter(cosConfig.corsFilter()); // cors 허용 설정 http.addFilterBefore(new MyFilter3(), SecurityContextPersistenceFilter.class); http.formLogin(login -> login.disable()); http.httpBasic(basic -> basic.disable()); http.addFilter(new JwtAuthenticationFilter(authenticationManager)); http.authorizeHttpRequests(request -> request.requestMatchers("/api/v1/user/**") .hasAnyRole("USER", "MANAGER", "ADMIN") .requestMatchers("/api/v1/manager/**") .hasAnyRole("MANAGER", "ADMIN") .requestMatchers("/api/v1/admin/**") .hasRole("ADMIN") .anyRequest().permitAll() ); return http.getOrBuild(); } 와 같이 SecurityConfig를 업데이트된 Spring Security 독스를 보고 선생님께서 강의해주신 내용대로 만들어보았습니다. 터미널에서는 JwtAuthentication Filter : 로그인 시도중 JwtAuthenticationFilter : UserEntity(id=0, email=null, password=qwer1234, username=ssar, role=null, createDate=null) JwtAuthenticationToken : 토큰생성완료 와 같이 JwtAuthenticationToken : 토큰생성완료 까지는 정상적으로 되는걸 확인하였습니다. 이후 loadByUsername() 부분에 따로 출력을 찍어 확인한결과 호출이 안되는걸 확인했습니다. @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserEntity userEntity = this.userDao.findByUsername(username); System.out.println("================ loadUserByUsername ================"); System.out.println(userEntity); System.out.println("---------------- loadUserByUsername -----------------"); return new PrincipalDetails(userEntity); } 어떤 부분이 잘못되어서 그런건지 찾지 못하여 게시글 남깁니다! 늘 좋은강의 감사합니다! 개인적으로 문제점이 된다고 생각한 부분 AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); 에서 authenticationManager를 받는 부분이 제대로 안되는것 같습니다... 추가로 SecurityConfig 에서 authenticationManager 부분을 로그로 찍어본 결과 null 출력되는걸 확인했습니다... authenticationManager부분이 생성이 안되는걸까요?
어디가 잘못된건지 못 찾겠습니다. 일단 boardList.jsp 에 boardForm.do 를 작성했는데 저는 계속해서 404에러와 아래 문구가 콘솔창에 찍힙니다. 도와주세요. 제 눈에는 잘못된 부분이 보이지 않습니다.... 현재 화면을 캡처해서 올립니다. servlet-context.xml BoardController boardList.jsp boardForm.jsp root-context.xml 결과창 : boardList는 잘 나옵니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? ( 예 /아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? ( 예 /아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? ( 예 /아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 안녕하세요. 해당 부분들을 공부하면서 제 자신의 정리가 확실하지 않아서 여쭤보고 싶습니다. 오버라이딩 된 Child.method()가 아닌 Parent.method()를 받으려면 super와 부모클래스의 업캐스팅을 통하여 해결하면 되다고 이해하면 될지 여쭤봅니다.
@Configuration public class BCryptConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } 위와 같이 Config class에 PasswordEncoder 빈을 생성했는데도 Description: Parameter 1 of constructor in domain.Member.service.MemberService required a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' that could not be found. Action: Consider defining a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' in your configuration. Process finished with exit code 1 와 같이 에러가 발생하면 어떻게 해야할까요?
안녕하세요! ElectricCar electricCar = new ElectricCar(); electricCar.move(); 이렇게 하면 호출한 electricCar 의 타입은 ElectiricCar 라서 인스턴스 내부의 ElectricCar 타입에서 시작한다고 하셨습니다. 그래서 electricCar.move(); 를 실행하면 ElectricCar 의 move() 메서드가 실행돼서 전기차를 빠르게 이동합니다. 이렇게 전기차로 출력이 됩니다. Car electricCar = new ElectricCar(); electricCar.move(); 그럼 이렇게 타입이 Car 타입이면 인스턴스 내부의 Car 타입에서 move() 메서드를 실행시켜 "차를 이동합니다."가 출력될 것이라고 생각했는데 전기차를 빠르게 이동합니다. 여기서도 전기차를 빠르게 이동합니다.가 출력됩니다. 어째서 Car 타입에서 move() 메서드를 실행하지 않고 ElectricCar 의 move() 메서드를 실행하게 되는건가요? 감사합니다!! 😊
안녕하세요~ 강의를 듣다가 제가 뭔가 잘못한건지 actuator에 refresh가 동작하지 않아 질문글을 남깁니다. 강의 2-10번 DB 비밀번호 암호화까지 문제 없이 잘 진행하다 재가동 없이 설정파일 갱신하는 부분을 진행하는데 item-service에서 build.gradle에 의존성 추가하고 bootstrap.yml에 설정 옵션 추가했는데 config-server 설정 파일 변경 후 postman 에서 refresh 요청을 날려도 response body 에는 [] 빈 배열만 찍히고 별다른 문구가 없고 변경된 설정이 적용되지 않더라고요 강의를 봐도 크게 설정하는 부분이 많은건 아니어서 잘 적용된 것 같은데 작동하지 않는 원인이 콘솔에 찍히지 않아서 헤메고 있습니다. build.gradle 의존성과 bootstrap.yml 에 설정 추가하고 config-server 실행시키고 item-service 실행시킨 후 설정 파일에 변경점을 주고 localhost:5000 번으로 /actuator/refresh 요청을 날렸습니다. 그리고 물품등록 요청을 보내서 200코드 성공했는데 별도의 logs 폴더에 api-local2.log는 생기지 않았습니다. 강의와 다르게 한건 인텔리제이로 프로젝트 구성한 것과 스프링부트 마이너 버전만 달라서 크게 문제가 있지는 않을 것 같은데.. 2-10 강의까지 해본 깃 주소도 올려봅니다. https://github.com/doyoun8813/Microservice
안녕하세요 영한님! 질문은 처음 드리는거 같습니다~ 기본형과 참조형 '문제와 풀이' 시간에 ProductOrder를 리팩토링하는 부분에서 질문이 있습니다. 리팩토링 하는 과정에서 for문 안에서 수행하던 print와 totalAmount를 계산하는 로직을 각각 메서드로 나누었는데요, 이렇게 되면 한번만 수행되던 반복문이 메서드로 나누면서 각각 수행되어 2번이 되는데 이런 부분은 for문이 한번 더 돌게되어 오는 성능이슈보다, 깔끔하게 리팩토링 되는 부분이 더 이점이 큰 부분일까요? 사실 현업에서 업무를 할때도, for안에서 여러가지 로직이 수행되면 한번에 파악하기가 어려워서 나눠야지 싶어서 나누었지만, 한번만 돌던 반복문이 여러번 돌게 될 수 있어서 망설여지는 부분이 있었습니다. 이 부분 질문드립니다! 감사합니다~