3

OAuth2 인증을 구현 중이며 왜 내 CustomCredentialsTokenEndpointFilter가 작동하지 않는지 이해할 수 없습니다.OAuth2 - 스프링 보안 : ClientCredentialsTokenEndpointFilter가 작동하지 않습니다.

디버깅 모드로 응용 프로그램을 시작하면 디버그 검사 점에 충돌이 발생하지 않습니다.

필터를 재정 의하여 인증 시도 구현을 변경해야합니다.

구성에 실수가 있습니까?

인증 어댑터 :

@Configuration 
@EnableWebSecurity 
@ComponentScan("com.springapp.mvc") 
@Order(3) 
class OAuth2AuthenticationConfigurationAdapter extends WebSecurityConfigurerAdapter { 

@Autowired 
private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler; 

@Autowired 
@Qualifier("clientDetailsService") 
private ClientDetailsService oauth2ClientDetailsService; 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .anonymous() 
      .disable(); 
    http 
      .requestMatchers() 
      .antMatchers("/oauth/token") 
     .and() 
      .authorizeRequests() 
      .anyRequest() 
      .fullyAuthenticated(); 
    http 
      .httpBasic() 
      .authenticationEntryPoint(oAuth2AuthenticationEntryPoint()) 
     .and() 
      .addFilterBefore(clientCredentialsTokenEndpointFilter(), BasicAuthenticationFilter.class) 
      .sessionManagement() 
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
     .and() 
      .exceptionHandling() 
      .accessDeniedHandler(oAuth2AccessDeniedHandler); 
} 

@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth 
      .userDetailsService(clientDetailsUserDetailsService()); 
} 

@Bean 
ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() { 
    final ClientCredentialsTokenEndpointFilter tokenEndpointFilter = new CustomClientCredentialsTokenEndpointFilter(); 
    try { 
     tokenEndpointFilter.setAuthenticationManager(authenticationManagerBean()); 
     tokenEndpointFilter.setAuthenticationEntryPoint(oAuth2AuthenticationEntryPoint()); 
     tokenEndpointFilter.setAuthenticationFailureHandler(authenticationFailureHandler()); 
     tokenEndpointFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler()); 
     tokenEndpointFilter.setAllowOnlyPost(true); 
     return tokenEndpointFilter; 
    } catch (Exception e) { 
     throw new IllegalStateException(e); 
    } 
} 

@Bean 
OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler() { 
    return new OAuth2AccessDeniedHandler(); 
} 

AuthenticationSuccessHandler authenticationSuccessHandler() { 
    return new OAuth2AuthenticationSuccessHandler(); 
} 

AuthenticationFailureHandler authenticationFailureHandler() { 
    return new OAuth2AuthenticationFailureHandler(); 
} 

UserDetailsService clientDetailsUserDetailsService() { 
    final ClientDetailsUserDetailsService service = new ClientDetailsUserDetailsService(oauth2ClientDetailsService); 

    return service; 
} 

@Bean 
OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint() { 
    final OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint(); 
    entryPoint.setRealmName("oauth/client"); 
    entryPoint.setTypeName("Basic"); 
    return entryPoint; 
} 

static final class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter { 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { 
     final Authentication authentication = super.attemptAuthentication(request, response); 

     return authentication; 
    } 
} 

static final class OAuth2AuthenticationFailureHandler implements AuthenticationFailureHandler { 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { 
     String s = request.toString(); 
    } 
} 

static final class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler { 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
     String s = request.toString(); 
    } 
} 

} 

의 HTTP 요청 : 요청을 발신 한 후

curl -X POST -H "Authorization: Basic **************************" -v -d "username=my.user&password=pass&client_id=my.user&cla-7c9d-426b-a942-cc166438f996&grant_type=password&scope=[read, write]" http://localhost:8080/oauth/token 

로그인합니다.

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is error="invalid_client", error_description="Given client ID does not match authenticated client" 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:943) 
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:833) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
</pre></p><p><b>root cause</b> <pre>error=&quot;invalid_client&quot;, error_description=&quot;Given client ID does not match authenticated client&quot; 
org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory.createTokenRequest(DefaultOAuth2RequestFactory.java:104) 
org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(TokenEndpoint.java:81) 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
java.lang.reflect.Method.invoke(Method.java:606) 
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214) 
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748) 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) 
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) 
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931) 
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:833) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 

예외가 발생한 위치와 원인을 파악하고이를 수정하려면 사용자 지정 필터를 제공해야합니다.

+0

스프링이 필터와 빈을 초기화하는 경우조차 알고 있습니까? 시작시, 디버그 로깅이 활성화 된 상태에서 Spring은 실제로 모든 필터 체인을 인쇄합니다. 필터가/oauth/token 문맥에 나타나는지 확인하십시오. – Misha

+0

@Misha에게 감사드립니다. Spring이 시작시 필터 체인 및 빈을 초기화한다는 사실을 알고있었습니다. 문제는 등록 된 필터가 호출되지 않는 이유를 모르겠다는 것입니다. curl로 요청을 보내면이 필터도 호출해야합니다. 그러나 그렇지 않습니다. 어떤 아이디어? –

+0

그건 내가 의미하는 바가 아니야. 실제로 적절한 필터 체인이 필터의 인스턴스를 가지고 있음을 로그에서 확인할 수 있습니까? – Misha

답변

1

좋아요, 설명은 here입니다. 사용자 정의 필터를 사용하려는 경우, 당신은

/OAuth를/토큰

경로를 사용할 수 없습니다.

그러나 사용자 지정 토큰 끝점을 구현하려고 시도했지만 경로 매핑에 성공하지 못했습니다. Someone did but the way it was done does not look elegant.

+1

더 좋아 보인다. http://stackoverflow.com/a/27860080/1643558 – tgkprog