2015-05-29 19 views
17

Tôi đang sử dụng Facebook trên mạng xã hội trong dự án Spring MVC để hỗ trợ đăng nhập Facebook. Điều này hoạt động tốt trong hầu hết các trường hợp, nhưng đôi khi tôi thấy ngoại lệ sau trong nhật ký.Facebook xã hội mùa xuân: "Thông số trạng thái OAuth2 'không khớp với"

ERROR org.springframework.social.connect.web.ProviderSignInController - Exception while completing OAuth 2 connection: 
java.lang.IllegalStateException: The OAuth2 'state' parameter doesn't match. 
at org.springframework.social.connect.web.ConnectSupport.verifyStateParameter(ConnectSupport.java:173) 
at org.springframework.social.connect.web.ConnectSupport.completeConnection(ConnectSupport.java:155) 
at org.springframework.social.connect.web.ProviderSignInController.oauth2Callback(ProviderSignInController.java:216) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:483) 
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at com.example.something.CorsFilter.doFilter(CorsFilter.java:49) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:673) 
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659) 
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

Tôi chưa thể tìm ra khi nào điều này xảy ra và tôi chưa thể tái tạo, nhưng tôi đã thấy nó xảy ra cho người dùng khác một vài lần. Dưới đây là cấu hình Facebook Xã hội mùa xuân của tôi.

@Configuration 
public class SocialConfig { 
    @Bean 
    public ProviderSignInController providerSignInController() { 
     ProviderSignInController controller = new ProviderSignInController(this.connectionFactoryLocator(), this.usersConnectionRepository(), new SpringSecuritySignInAdapter(this.accountRepository)); 
     controller.addSignInInterceptor(new RedirectToPreviousPageInterceptor(controller, this.analyticsService)); 

     return controller; 
    } 

    @Bean 
    public ConnectionFactoryRegistry connectionFactoryLocator() { 
     ConnectionFactoryRegistry connectionFactoryRegistry = new ConnectionFactoryRegistry(); 
     List<ConnectionFactory<?>> connectionFactories = new ArrayList<ConnectionFactory<?>>(); 
     connectionFactories.add(this.facebookConnectionFactory()); 
     connectionFactoryRegistry.setConnectionFactories(connectionFactories); 

     return connectionFactoryRegistry; 
    } 

    @Bean 
    public FacebookConnectionFactory facebookConnectionFactory() { 
     FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory(this.facebookAppId, this.facebookAppSecret); 
     connectionFactory.setScope(this.scope); 

     return connectionFactory; 
    } 

    @Bean 
    @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES) 
    public Facebook facebook(ConnectionRepository repository) { 
     Connection<Facebook> connection = repository.findPrimaryConnection(Facebook.class); 
     return (connection != null ? connection.getApi() : null); 
    } 

    @Bean 
    @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES) 
    public ConnectionRepository connectionRepository() { 
     Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 

     if (authentication == null) { 
      throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in"); 
     } 

     Account account = (Account) authentication.getPrincipal(); 
     return this.usersConnectionRepository().createConnectionRepository(String.valueOf(account.getId())); 
    } 

    @Bean 
    public JdbcUsersConnectionRepository usersConnectionRepository() { 
     JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(this.dataSource, this.connectionFactoryLocator(), this.textEncryptor); 
     repository.setConnectionSignUp(this.accountService); 

     return repository; 
    } 
} 

Tại sao điều này xảy ra và tôi có thể làm gì để ngăn chặn điều này? Cảm ơn.

Trả lời

2

Chức năng này chỉ tạo chuỗi giá trị trạng thái (theo mặc định UUID.randomUUID().toString()), đặt nó trong phiên và chuyển nó cho nhà cung cấp dưới dạng thông số "trạng thái" trong yêu cầu ủy quyền. Các nhà cung cấp dự kiến ​​sẽ vượt qua nó trở lại trên gọi lại. Nếu trạng thái được lưu trữ khớp với trạng thái trong cuộc gọi lại, thì chúng ta sẽ tốt. Nếu họ không phù hợp, đó là khi bạn thấy ngoại lệ mà bạn đã đề cập ở đó.

Điều này chỉ có nghĩa là phải làm việc, nhưng có tôi thấy rằng bạn đang gặp vấn đề ở đây. Tôi cũng tìm thấy liên kết này có thể đáng xem: https://github.com/spring-projects/spring-social-facebook/issues/103

+0

Cảm ơn bạn đã giải thích.Tôi vẫn không biết trong trường hợp nào các giá trị không khớp. Trước đây tôi đã xem xét vấn đề đó, nhưng có vẻ như Facebook đã sửa nó, nên tôi không nghĩ nhiều hơn. – Andy0708

+0

Tôi đang chạy vào một vấn đề với một tham số trạng thái null. Tôi sử dụng Spring Social. Tôi phải làm gì đó sai với cấu hình của mình. Tôi đã mở một chủ đề ở đây: http://stackoverflow.com/q/39469165/536299 Ai đó có thể giúp đỡ không? – balteo

7

Thông số state ngăn các tấn công CSRF trong OAuth2.

Ý tưởng hạnh phúc:

  • Ứng dụng của bạn thêm một tham số state để yêu cầu rằng nó làm cho đến máy chủ xác thực (trong trường hợp này, Facebook)
  • Máy chủ xác thực vang giá trị chính xác của state rằng tham số lại cho bạn trong phản ứng
  • sau đó, bạn hãy kiểm tra xem chúng có giống nhau lên

Nghe có vẻ vô nghĩa ... nhưng nó ngăn cản kẻ tấn công thực hiện các yêu cầu hành động ứng dụng khách của bạn mà nó không khởi tạo.

này đề cập đến nó rất chi tiết: xử lý

http://www.twobotechnologies.com/blog/2014/02/importance-of-state-in-oauth2.html

mùa xuân xã hội tất cả điều này cho bạn: tạo ra một mới ngẫu nhiên state cho mọi yêu cầu, và tự động cố gắng để phù hợp với nó để giá trị trong các phản ứng.

Vì vậy bạn không thể ngăn chặn nó:, và bạn không muốn: những có thể là chính hãng nỗ lực tấn công thất bại - và trong những trường hợp, bạn muốn lỗi này xảy ra.

Đối với trường hợp bạn đã đăng, có thể chỉ cần xử lý lỗi thông số state của Spring Social hoặc bằng máy chủ xác thực của Facebook.

Nhưng, về phía bạn, bạn nên xử lý ngoại lệ như thể đó là nỗ lực tấn công chính hãng: đăng nhập cảnh báo/cảnh báo người/v.v.

+0

Cảm ơn bạn đã giải thích. Tôi hiểu mục đích của tham số 'state', và như bạn nói, tôi thực sự không quan tâm đến việc loại bỏ nó. Tôi sẽ cố gắng điều tra thêm. Cảm ơn một lần nữa. – Andy0708

Các vấn đề liên quan