묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 시큐리티 OAuth2
logoutHandler 질문입니다.
로그아웃 api 설정에선 logoutSuccessHandler, invalidateHttpSession, clearAuthentication, deleteCookies 만 설정했는데 logoutFilter에 왜 인가서버에 로그아웃을 요청하는 logoutHandler가 있는건가요? OAuth2 라이브러리 의존성 추가하면 자동으로 추가되는건가요? 맞다면 logout api설정으로 먼저 클라이언트에서 세션, 쿠키, 인증 객체를 제거하고 이후 인가서버에서 해당 유저의 세션을 제거하는 logoutHandler가 호출돼서 인가서버에서 세션 삭제하고, 로그아웃 성공했으니 logoutSuccessHandler에서 설정한 RedirectUri로 이동하는건가요? 아니면 클라이언트에서 인증정보 제거후 logoutSuccessHandler에 설정한 객체가 호출돼고 이 Handler에서 인가서버에 세션제거하고 redirect하게 하는건가요?
-
미해결스프링 시큐리티 OAuth2
openid 질문입니다.
Scope 에 openid 가 포함되어 있으면 OidcAuthorizationCodeAuthenticationProvider 를 호출하고 아니면 OAuth2AuthorizationCodeAuthenticationProvider 를 호출하도록 제어된다고 돼있는데, 최신버전의 keycloak에선 scope에 openid가 없으면 에러가 발생하도록 돼있어서 반드시 openid를 포함시켜줘야 하는데, 그러면 인가서버로 keycloak 쓸때는 OidcAuthorizationCodeAuthenticationProvider 가 호출된다고 보면 되겠네요?
-
미해결스프링 시큐리티 OAuth2
스프링시큐리티 기본 제공 password 질문입니다.
프로젝트 의존성에 implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'즉, oauth2 의존성을 추가하면 프로젝트 실행시 콘솔에 스프링 시큐리티가 기본으로 제공하는 password가 안나오는데 oauth2 의존성을 제거하고 실행해보면 기본으로 제공하는 password가 콘솔에 나옵니다. 강의랑 다른거 같은데 이유가 뭘까요? 최신버전에 따른 차이인가요?
-
미해결스프링 시큐리티 OAuth2
JwtDecoder 문제
org.springframework.boot:spring-boot-starter-oauth2-resource-server:2.7.3 버전에서 jwtDecoder 생성 문제가 있는 것으로 보입니다.jwt-set-uri 설정일때는 되지 않고 issuer-uri 설정일때만 문제가 발생하지 않습니다.혹시 제가 설정 문제인지 확인 차 질문드립니다.url 확인도 해봤습니다. https://github.com/okta/samples-java-spring/issues/77여기서 문제가 있다며, 일부분을 인정을 하였습니다.같은 상황으로 보입니다.
-
미해결스프링 시큐리티 OAuth2
authenticationEntryPoint 질문입니다.
강의 10분22초 강의자료 그림에서 인증이 실패하면 DaoAuthenticationProvider가 BasicAuthenticationEntryPoint를 호출한다고 돼있는데, AuthenticationEntryPoint는 이 과정에서의 실패가 아니라 해당 필터를 지나서 AuthorizationFilter에서 인증이 안된 사용자가 권한으로 인해 예외가 발생했을 경우 호출되는거 아닌가요? UsernameAuthenticationFilter에선 이런식이였던거 같은데 제가 잘못 이해한걸까요? DaoAuthenticationProvider에서 인증이 실패하면 BasicAuthenticationEntryPoint가 아니라 해당 필터에 등록된 FailureHandler가 호출되야할거 같은데 설명 부탁드립니다!
-
미해결스프링 시큐리티 OAuth2
rsa 512 복호화 에러
org.springframework.security.oauth2.jwt.BadJwtException: An error occurred while attempting to decode the Jwt: Signed JWT rejected: Invalid signature at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.createJwt(NimbusJwtDecoder.java:180) ~[spring-security-oauth2-jose-5.7.3.jar:5.7.3] at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.decode(NimbusJwtDecoder.java:137) ~[spring-security-oauth2-jose-5.7.3.jar:5.7.3] at io.security.oauth2.resource.server.filter.authorization.JwtAuthorizationRsaPublicKeyFilter.doFilterInternal(JwtAuthorizationRsaPublicKeyFilter.java:38) ~[classes/:na] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:112) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) ~[spring-security-web-5.7.3.jar:5.7.3] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.22.jar:5.3.22] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.22.jar:5.3.22] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.65.jar:9.0.65] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]Caused by: com.nimbusds.jose.proc.BadJWSException: Signed JWT rejected: Invalid signature at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:378) ~[nimbus-jose-jwt-9.22.jar:9.22] at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:303) ~[nimbus-jose-jwt-9.22.jar:9.22] at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.createJwt(NimbusJwtDecoder.java:154) ~[spring-security-oauth2-jose-5.7.3.jar:5.7.3] ... 57 common frames omitted이런 에러가 발생하고 있습니다. 이유를 잘 모르겠습니다.
-
미해결스프링 시큐리티 OAuth2
스피링 시큐리티 강의 너무 좋습니다
시큐리티 강의를 만들어주셔서 너무 감사합니다!디버깅을 통한 내부 아키텍처 동작원리 이해가 너무재밌습니다 ㅎㅎ 시큐리티에 대한 거부감이 초반에 있었지만, 스프링 시큐리티 동작원리를 이해하게 되므로써 시큐리티가 재밌어지고 활용도 잘할것 같습니다. 그리고 내부 디버깅을 하면서 느낀게 코드 디자인 설계 특히 디자인 패턴에 대해서도 많이 공부할 수 있게되어서 좋은 공부 방향인것 같습니다 ㅎㅎ 다시한번 감사의 말씀을 드립니다.
-
미해결스프링 시큐리티 OAuth2
네이버 로그인 시 권한
네이버로 로그인하면 권한이 yml에 설정한 scope - email, profile은 넘어오지 않습니다. 강사님과 코드도 동일한데 어디를 확인해봐야할까요?
-
미해결스프링 시큐리티 OAuth2
jwt login flow에 대해서 질문드립니다.
현재 login post 요청만 되는 것으로 확인이 됩니다.1. login post요청만 받을 수 있도록 설정되어 있는 클래스가 궁금합니다.2. 기존에 있던 loginfilter가 사라지고 현재는 어떤 필터로 대체 되었는지 알고 싶습니다.3. http.addFilterBefore(jwtAuthenticationFilter(macSecuritySigner, octetSequenceKey), UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(jwtAuthorizationMacFilter(octetSequenceKey), UsernamePasswordAuthenticationFilter.class);현재 이렇게 코드가 있는데, 인증일 경우 jwtAuthenticationFilter만 권한 검증일 경우 jwtAuthorizationMacFilter로 가는지 여부 결정하는 과정에 대해서 설명부탁드립니다.
-
미해결스프링 시큐리티 OAuth2
login 성공 이후 error페이지
302 status 이후 error 페이지로 이동하는 문제가 있습니다.어떤걸 확인해야될까요?
-
미해결스프링 시큐리티 OAuth2
OAuth2 form login error
OAuth 2.0 Social Login 연동 구현 (6) 부분에 있는 영상 33:46까지 따라왔지만 form로그인에서 발생한 문제입니다. form login의 inmemory나 jdbc형태로 하는 게 아닌 CustomUserDetailsService를 통해서만 인증을 하는 것으로 보이는데, 이와 같은 에러가 발생하는 이유를 모르겠습니다. (에러코드가 조회되지 않음) 디버그 모드를 확인해보니, DaoAuthenticationProvider클래스에 있는 additionalAuthenticationChecks메소드에서 에러가 발생하고 있습니다.if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { this.logger.debug("Failed to authenticate since password does not match stored value"); throw new BadCredentialsException(this.messages .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); } 2. presentedPassword 이부분이 값이 빈값으로 넣어지고 있는데 문제가 되는 부분인 것 같아 질문드립니다.2-1. 추가적으로 이부분은 첫 로그인이라서 에러나는 부분하고 상관이 없이 발생하는지 질문드립니다. 에러로그가 확인이 불가능하여, 코드 공유를 위해 프로젝트 공유를 하였습니다. 확인 부탁드립니다.
-
미해결스프링 시큐리티 OAuth2
oidc 로그인
선생님 구글 로그인은 oauth2Login() 을 사용하지만 결국에는 oidc Scope를 사용하기 때문에 oidc 인증 프로토콜을 사용해서 인증절차를 사용한다고 보면 될까요?
-
미해결스프링 시큐리티 OAuth2
Spring Authorization Server 활용 sso 구축
Oauth를 활용해 자체 sso 서버를 구축하려고 하는데 궁금한 게 있어 문의 드립니다.먼저 구축할 예정인 환경은 아래와 같습니다.로그인 프론트 Authorization과 로그인을 함께 처리할 백엔드 authorization code 요청 시 로그인 여부를 확인해야 하는데 로그인 정보가 jwt 토큰으로 cookie에 담겨있다면, OAuth2AuthorizationEndpointFilter에서 확인을 해야하는지 OAuth2AuthorizationCodeRequestAuthenticationConverter에서 확인을 해야하는지 궁금합니다.
-
미해결스프링 시큐리티 OAuth2
OAuth 2.0 Grant Flows 관련 질문
안녕하세요. OAuth 2.0을 배우고 싶어 학습 신청했습니다.유익한 강의 준비해주셔서 감사합니다.막연하게 알고 있는 Spring Security 에 대해 강의를 통해 명확하게 알아가고 있습니다. 강의를 들으며 몇가지 궁금한 점이 있어 질문드립니다. 우선은 자체 로그인만 구현할 예정이라면,소셜 로그인 기능이 없는 경우에는 OAuth 2.0을 도입할 필요가 없는 건가요?Resource Owner Password Credentials Grant Flow 는 Deprecated 된다고 하는데 그럼 어떻게 구현해야하나요? 답변주시면 성장하는데 큰 도움이 될 것 같습니다!감사합니다!
-
해결됨스프링 시큐리티 OAuth2
시큐리티 완전정복(6.x 개정판) 쿠폰 저도 받을수 있을까요.. ㅜ
학습질문과 전혀 관련없는 질문이라 죄송합니다. ㅠ저와같이 할인쿠폰 만료일 지나신 분 쿠폰요청글을 보고 혹시나 저도 아직 가능한지 여쭙고 싶어서 혹시나 하는 마음에 글올립니다.oAuth하고 이전버전 시큐리티 강의 듣고 있습니다.저도 메일을 늦게 확인하여서 쿠폰 만료일이 지났는데받을수있을까요?발급받았던 이메일 주소 는laundryday@naver.com입니다.. 좋은 하루 보내세요 감사합니다.
-
미해결스프링 시큐리티 OAuth2
비대칭키 내용 중 궁금한게 있습니다.
데이터 보안 측면에서 송신자 공개키로 암호화 -> 송신자 개인키로 복호화를 한다고 적혀있는데요.수신자가 송신자의 개인키를 가지고 있다는게 보안적으로 문제가 되는게 아닌가 싶습니다. 수신자 공개키로 암호화 -> 수신자 개인키로 복호화의 오타인 것인지, 아니라면 어떻게 보안적으로 괜찮은건지 궁금합니다.
-
미해결스프링 시큐리티 OAuth2
시큐리티 완전정복(6.x 개정판) 쿠폰
안녕하세요!!수원님의 시큐리티 강의를 듣고 있습니다!!좋은 강의 해주셔서 감사합니다!다름이 아니라, 제가 메일을 늦게 확인하여서기존 수강생에게 제공되는 50%할인 쿠폰을 사용하지 못했는데,혹시 다시 쿠폰 발급이 가능한지 여쭤봐도 되겠습니까?!감사합니다.
-
미해결스프링 시큐리티 OAuth2
access token 의 용도
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. keycloak,kakao 같은 authorization server 에서 발급하는 access token 은 userinfo 를 가져오기 위한 token 이라고 생각했는데, resource server 같은 자원도 이 토큰으로 접근 하는게 맞는지 궁금합니다. 수업을 위한 예제인지 실제로 이렇게 사용을 많이 하는지요. 카카오같은 인증서버에서 받은 access token 은 카카오에서 유저 정보를 가져오기 위함이고, resource server 의 다른 api 접근 목적은 아니라고 생각했었는데요. 제가 잘못 알고 있었는지 궁금합니다.
-
미해결스프링 시큐리티 OAuth2
client 의 token 발행 가능 여부
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. keycloak 을 authorization server 로 사용하는데요.키클록에 등록되는 유저와 유저별 권한과 별개로,서비스의 메뉴별 권한을 상세 설정하기 위해서 client 에서 서비스 권한 관리를 하고 메뉴 접근 권한 관련된 token 을 발행한다고 하면, resource-server 에 jwt-set-uri 를 client 서버 endpoint 로 하고, client 에서 jwkset 을 반환하는 방식이 가능한지 궁금합니다.
-
미해결스프링 시큐리티 OAuth2
client-credentials 방식 accessToken null 이슈
Cannot invoke "org.springframework.security.oauth2.client.OAuth2AuthorizedClient.getAccessToken()" because "oAuth2AuthorizedClient" is null] with root causekeycloak 버전은 : 21.1.2 @GetMapping("/oauth2Login") public String oauth2Login(Model model, HttpServletRequest request, HttpServletResponse response) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest .withClientRegistrationId("keycloak") .principal(authentication) .attribute(HttpServletRequest.class.getName(), request) .attribute(HttpServletResponse.class.getName(), response) .build(); OAuth2AuthorizationSuccessHandler successHandler = (authorizedClient, principal, attributes) -> { oAuth2AuthorizedClientRepository .saveAuthorizedClient(authorizedClient, principal, (HttpServletRequest) attributes.get(HttpServletRequest.class.getName()), (HttpServletResponse) attributes.get(HttpServletResponse.class.getName())); System.out.println("authorizedClient : " + authorizedClient); System.out.println("principal : " + principal); System.out.println("attributes : " + attributes); }; auth2AuthorizedClientManager.setAuthorizationSuccessHandler(successHandler); OAuth2AuthorizedClient oAuth2AuthorizedClient = auth2AuthorizedClientManager.authorize(oAuth2AuthorizeRequest); model.addAttribute("oAuth2AuthorizedClient", oAuth2AuthorizedClient.getAccessToken().getTokenValue()); return "home"; } keycloak: clientId: oauath2-client-app clientSecret: HPWAsKr9dEy9DPU1babedRmpstowiXOs clientName: oauath2-client-app authorizationGrantType: client-credentials clientAuthenticationMethod: client_secret_basic provider: keycloak <form sec:authorize="isAnonymous()" action="#"> <p><input type="button" onclick="authorizationCode()" value="AuthorizationCode Grant"/></p> <p><div sec:authorize="isAnonymous()"><a th:href="@{/oauth2Login(username='user',password='1234')}">Password flow</a></div></p> <div sec:authorize="isAnonymous()"><a th:href="@{/oauth2Login}">Client Credentials Flow Login</a></div> </form> @Configuration public class AppConfig { @Bean public DefaultOAuth2AuthorizedClientManager auth2AuthorizedClientManager(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepository) { OAuth2AuthorizedClientProvider oAuth2AuthorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .authorizationCode() .password() .clientCredentials() .refreshToken() .build(); DefaultOAuth2AuthorizedClientManager defaultOAuth2AuthorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, oAuth2AuthorizedClientRepository); defaultOAuth2AuthorizedClientManager.setAuthorizedClientProvider(oAuth2AuthorizedClientProvider); defaultOAuth2AuthorizedClientManager.setContextAttributesMapper(contextAttributeManager()); return defaultOAuth2AuthorizedClientManager; } private Function<OAuth2AuthorizeRequest, Map<String, Object>> contextAttributeManager() { return oAuth2AuthorizeRequest -> { Map<String, Object> contextAttributes = new HashMap<>(); HttpServletRequest httpServletRequest = oAuth2AuthorizeRequest.getAttribute(HttpServletRequest.class.getName()); String userName = httpServletRequest.getParameter(OAuth2ParameterNames.USERNAME); String userPassword = httpServletRequest.getParameter(OAuth2ParameterNames.PASSWORD); if(StringUtils.hasText(userName) && StringUtils.hasText(userPassword)) { contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, userName); contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, userPassword); } return contextAttributes; }; } } 이렇게 됩니다. 현재 상황으로 문제가 되어 있는 부분이 없는 것 같습니다.어디부터 다시 확인해야 될지 조언 부탁드립니다.