Spring social The OAuth2 'state' parameter is missing or doesn't match

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

I'm developing a spring boot application and I need to use spring social login for facebook. I tried different strategies and tutorials to achieve that, but every time after user is redirected from facebook to my application, I get the error saying 'state' parameter doesn't exist or not match. I know this parameter is something like CSRF protection and I can see that spring is sending it when user is redirecting to facebook. But I almost get lost inside facebook response. I can see the parameter exists in the set-cookie header from facebook, but not as a parameter.

I can see more people have faced this issue before, but none of the answers worked for me and they were quite old questions. There is also an open issue on github about this. Is it a bug? or cant it be fixed through some configuration?

I'm using spring security and spring session redis in this project too. While I have tried many different configuration, here is the last one I have been working on:

SOCIAL CONFIG

@Configuration @EnableSocial public class SocialConfig         implements SocialConfigurer {       private final Environment environment;     private final MongoOperations mongoOperations;     private final FacebookConnectionSignup facebookConnectionSignup;      @Autowired     public SocialConfig(Environment environment, MongoOperations mongoOperations, FacebookConnectionSignup facebookConnectionSignup) {         this.environment = environment;         this.mongoOperations = mongoOperations;         this.facebookConnectionSignup = facebookConnectionSignup;     }      @Bean     public TextEncryptor textEncryptor(){         return noOpText();     }       @Override     public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) {         connectionFactoryConfigurer.addConnectionFactory(new FacebookConnectionFactory(                 environment.getProperty("spring.social.facebook.appId"),                 environment.getProperty("spring.social.facebook.appSecret")));     }      @Override     public UserIdSource getUserIdSource() {         return new AuthenticationNameUserIdSource();     }      @Override     public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {         MongoUsersConnectionRepository mongoUsersConnectionRepository = new MongoUsersConnectionRepository(                 mongoOperations,                 connectionFactoryLocator,                 new MongoConnectionTransformers(                     connectionFactoryLocator,                     textEncryptor()                 )         );         mongoUsersConnectionRepository.setConnectionSignUp(facebookConnectionSignup);         return mongoUsersConnectionRepository;     }      @Bean     public SocialUserDetailsService socialUserDetailsService(UserDetailsService customUserDetailsService){         return new SimpleSocialUserDetailsService(customUserDetailsService);     }  } 

SECURITY CONFIG

@Configuration @EnableGlobalMethodSecurity() @EnableRedisHttpSession @Order(-10) public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {      @Override     protected void configure(HttpSecurity http) throws Exception {         http                 .httpBasic().disable()                 .csrf().disable()                 .sessionManagement()                 .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) //                .sessionFixation().changeSessionId()                 .and()                 .authorizeRequests()                     .antMatchers("/").permitAll()                     .antMatchers("/admin/**").authenticated()                     .antMatchers("/m/**").authenticated()                 .and()                 .headers().frameOptions().disable()                 .and()                 .requestCache()                 .requestCache(new NullRequestCache())                 .and()                 .cors()                 .and()                 .rememberMe()                 .and().logout().clearAuthentication(true).logoutSuccessHandler(customLogoutSuccessHandler)                 .and().apply(new SpringSocialConfigurer()                                     .postLoginUrl("/")                                     .defaultFailureUrl("/#/login")                                     .alwaysUsePostLoginUrl(true));     }      @Bean     public PasswordEncoder passwordEncoder() {         return new BCryptPasswordEncoder();     }      @Bean     public static AuthenticationTrustResolver getAuthenticationTrustResolver() {         return new AuthenticationTrustResolverImpl();     }      @Bean("authenticationManager")     @Override     public AuthenticationManager authenticationManagerBean() throws Exception {         return super.authenticationManagerBean();     }       @Override     protected void configure(AuthenticationManagerBuilder auth) throws Exception {         auth.userDetailsService(customUserDetailsService);     }      @Bean     public CookieSerializer cookieSerializer() {         DefaultCookieSerializer serializer = new DefaultCookieSerializer();         serializer.setCookieName(Setting.COOKIE_NAME);         serializer.setCookiePath("/");         serializer.setUseSecureCookie(false);         serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");         return serializer;     }      @Bean     public ProviderSignInController providerSignInController() throws Exception {         ((MongoUsersConnectionRepository) usersConnectionRepository)                 .setConnectionSignUp(facebookConnectionSignup);          ProviderSignInController providerSignInController = new ProviderSignInController(                 connectionFactoryLocator, usersConnectionRepository, facebookSignInAdapter);         List<ProviderSignInInterceptor<?>> list = new ArrayList<>();         list.add(new FacebookConnectionInterceptor());         providerSignInController.setSessionStrategy(new HttpSessionSessionStrategy());         providerSignInController.setSignInInterceptors(list);         providerSignInController.afterPropertiesSet();         return providerSignInController;     }   } 

SIGNIN ADAPTER

@Component public class FacebookSignInAdapter implements SignInAdapter {     private UserService userService;     private AuthenticationService authenticationService;      @Autowired     public FacebookSignInAdapter(UserService userService, AuthenticationService authenticationService) {         this.userService = userService;         this.authenticationService = authenticationService;     }      @Override     public String signIn(             String localUserId,             Connection<?> connection,             NativeWebRequest request) {          final String email = connection.getDisplayName();          final UserEntity userEntity = userService.getUserEntityFromUnknownIdentity(email);         authenticationService.authenticateWithoutPassword(userEntity.getUsername());          return email;     } } 

I'm running this on localhost:8080. The exception:

2018-09-01 09:48:16.054 ERROR 7169 --- [nio-8080-exec-6] o.s.s.c.web.ProviderSignInController     : Exception while completing OAuth 2 connection:   java.lang.IllegalStateException: The OAuth2 'state' parameter is missing or doesn't match.     at org.springframework.social.connect.web.ConnectSupport.verifyStateParameter(ConnectSupport.java:173) ~[spring-social-web-1.1.6.RELEASE.jar:1.1.6.RELEASE]     at org.springframework.social.connect.web.ConnectSupport.completeConnection(ConnectSupport.java:155) ~[spring-social-web-1.1.6.RELEASE.jar:1.1.6.RELEASE]     at org.springframework.social.connect.web.ProviderSignInController.oauth2Callback(ProviderSignInController.java:228) ~[spring-social-web-1.1.6.RELEASE.jar:1.1.6.RELEASE]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]     at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]     at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.32.jar:8.5.32]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90) [spring-boot-actuator-2.0.4.RELEASE.jar:2.0.4.RELEASE]     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]     at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at ...  2018-09-01 10:05:50.679  INFO 7169 --- [io-8080-exec-10] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header  Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.  java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens     at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:428) ~[tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:684) ~[tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.32.jar:8.5.32]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.32.jar:8.5.32]     at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181] 

EXTRA INFO


Here is the request timeline provided by insomnia where I am testing the login process.

> POST /signin/facebook HTTP/1.1 > Host: localhost:8080 > User-Agent: insomnia/6.0.2 > Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY > Accept: */* > Content-Length: 112 | --X-INSOMNIA-BOUNDARY | Content-Disposition: form-data; name="scope" | public_profile | --X-INSOMNIA-BOUNDARY--   < HTTP/1.1 302  < X-Content-Type-Options: nosniff < X-XSS-Protection: 1; mode=block < Cache-Control: no-cache, no-store, max-age=0, must-revalidate < Pragma: no-cache < Expires: 0 < Set-Cookie: JSESSIONID=MzA4YjJiZGMtNmU1Yy00ODQ0LWFiNDYtYjkyZjg5NjVjYTc4; Path=/; HttpOnly < Location: https://www.facebook.com/v1.0/dialog/oauth?client_id=*****************&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsignin%2Ffacebook&scope=public_profile&state=d8a641c9-8748-4a95-b603-737c956a99a9 < Content-Language: en-US < Content-Length: 0 < Date: Sat, 01 Sep 2018 05:18:07 GMT   > POST /v1.0/dialog/oauth?client_id=*****************&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsignin%2Ffacebook&scope=public_profile&state=d8a641c9-8748-4a95-b603-737c956a99a9 HTTP/1.1 > Host: www.facebook.com > User-Agent: insomnia/6.0.2 > Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY > Accept: */* > Content-Length: 112 | --X-INSOMNIA-BOUNDARY | Content-Disposition: form-data; name="scope" | public_profile | --X-INSOMNIA-BOUNDARY--   < HTTP/1.1 302 Found < X-XSS-Protection: 0 < Pragma: no-cache < Location: https://m.facebook.com/v3.1/dialog/oauth?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsignin%2Ffacebook&state=d8a641c9-8748-4a95-b603-737c956a99a9&scope=public_profile&response_type=code&client_id=***************** < Cache-Control: private, no-cache, no-store, must-revalidate < X-Frame-Options: DENY < Strict-Transport-Security: max-age=15552000; preload < X-Content-Type-Options: nosniff < Expires: Sat, 01 Jan 2000 00:00:00 GMT < facebook-api-version: v3.1 < Content-Type: text/html; charset="utf-8" < X-FB-Debug: IzMwWhuz/h6oL3pLb7+7KWm0ll5EAPKo3e2aJjVwLkGcGvkIKH2tDaWQM0P3LSSygnoxsBBkn343+xe0I+flRQ== < Date: Sat, 01 Sep 2018 05:18:07 GMT < Connection: keep-alive < Content-Length: 0   > POST /v3.1/dialog/oauth?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsignin%2Ffacebook&state=d8a641c9-8748-4a95-b603-737c956a99a9&scope=public_profile&response_type=code&client_id=***************** HTTP/1.1 > Host: m.facebook.com > User-Agent: insomnia/6.0.2 > Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY > Accept: */* > Content-Length: 112 | --X-INSOMNIA-BOUNDARY | Content-Disposition: form-data; name="scope" | public_profile | --X-INSOMNIA-BOUNDARY-- * We are completely uploaded and fine < HTTP/1.1 302 Found < Location: https://m.facebook.com/login.php?skip_api_login=1&api_key=*****************&signed_next=1&next=https%3A%2F%2Fm.facebook.com%2Fv3.1%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%26scope%3Dpublic_profile%26response_type%3Dcode%26client_id%3D*****************%26ret%3Dlogin%26logger_id%3Dfb742942-3c31-c425-5749-882c6c0ef46c&cancel_url=http%3A%2F%2Flocalhost%3A8080%2Fsignin%2Ffacebook%3Ferror%3Daccess_denied%26error_code%3D200%26error_description%3DPermissions%2Berror%26error_reason%3Duser_denied%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%23_%3D_&display=touch&locale=en_GB&logger_id=fb742942-3c31-c425-5749-882c6c0ef46c&_rdr < X-Frame-Options: DENY < X-XSS-Protection: 0 < Cache-Control: private, no-cache, no-store, must-revalidate < Expires: Sat, 01 Jan 2000 00:00:00 GMT < Access-Control-Allow-Origin: https://m.facebook.com < Access-Control-Expose-Headers: X-FB-Debug, X-Loader-Length < Pragma: no-cache < Vary: Origin < Access-Control-Allow-Credentials: true < Access-Control-Allow-Methods: OPTIONS < Strict-Transport-Security: max-age=15552000; preload; includeSubDomains < Content-Type: text/html; charset=utf-8 < X-Content-Type-Options: nosniff < facebook-api-version: v3.1 < Set-Cookie: datr=DyGKW_ZKdOwz5HKz9nMlERCC; expires=Mon, 31-Aug-2020 05:18:07 GMT; Max-Age=63072000; path=/; domain=.facebook.com; secure; httponly < Set-Cookie: reg_fb_ref=https%3A%2F%2Fm.facebook.com%2Fv3.1%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%26scope%3Dpublic_profile%26response_type%3Dcode%26client_id%3D*****************; path=/; domain=.facebook.com; secure; httponly < Set-Cookie: reg_fb_gate=https%3A%2F%2Fm.facebook.com%2Fv3.1%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%26scope%3Dpublic_profile%26response_type%3Dcode%26client_id%3D*****************; path=/; domain=.facebook.com; secure; httponly < X-FB-Debug: mTfLJKXvLxLJkSzdZfSkNjnljOEAKuIf+Wn7qnRU85Cd0FhFNebW5D6zCharUAZdfK89GRl886DDq3l2q1m6RQ== < Date: Sat, 01 Sep 2018 05:18:07 GMT < Connection: keep-alive < Content-Length: 0  > POST /login.php?skip_api_login=1&api_key=*****************&signed_next=1&next=https%3A%2F%2Fm.facebook.com%2Fv3.1%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%26scope%3Dpublic_profile%26response_type%3Dcode%26client_id%3D*****************%26ret%3Dlogin%26logger_id%3Dfb742942-3c31-c425-5749-882c6c0ef46c&cancel_url=http%3A%2F%2Flocalhost%3A8080%2Fsignin%2Ffacebook%3Ferror%3Daccess_denied%26error_code%3D200%26error_description%3DPermissions%2Berror%26error_reason%3Duser_denied%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%23_%3D_&display=touch&locale=en_GB&logger_id=fb742942-3c31-c425-5749-882c6c0ef46c&_rdr HTTP/1.1 > Host: m.facebook.com > User-Agent: insomnia/6.0.2 > Cookie: datr=DyGKW_ZKdOwz5HKz9nMlERCC; reg_fb_gate=https%3A%2F%2Fm.facebook.com%2Fv3.1%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%26scope%3Dpublic_profile%26response_type%3Dcode%26client_id%3D*****************; reg_fb_ref=https%3A%2F%2Fm.facebook.com%2Fv3.1%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%26state%3Dd8a641c9-8748-4a95-b603-737c956a99a9%26scope%3Dpublic_profile%26response_type%3Dcode%26client_id%3D***************** > Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY > Accept: */* > Content-Length: 112 | --X-INSOMNIA-BOUNDARY | Content-Disposition: form-data; name="scope" | public_profile | --X-INSOMNIA-BOUNDARY--  < HTTP/1.1 200 OK < X-Frame-Options: DENY < X-XSS-Protection: 0 < Cache-Control: private, no-cache, no-store, must-revalidate < Access-Control-Allow-Origin: https://m.facebook.com < Access-Control-Expose-Headers: X-FB-Debug, X-Loader-Length < Pragma: no-cache < Vary: Origin < Content-Type: text/html; charset=utf-8 < X-Content-Type-Options: nosniff < Access-Control-Allow-Credentials: true < Access-Control-Allow-Methods: OPTIONS < Strict-Transport-Security: max-age=15552000; preload; includeSubDomains < Expires: Sat, 01 Jan 2000 00:00:00 GMT < Set-Cookie: datr=DyGKW_ZKdOwz5HKz9nMlERCC; expires=Mon, 31-Aug-2020 05:18:08 GMT; Max-Age=63072000; path=/; domain=.facebook.com; secure; httponly < Set-Cookie: reg_fb_ref=https%3A%2F%2Fm.facebook.com%2Flogin.php%3Fskip_api_login%3D1%26api_key%3D*****************%26signed_next%3D1%26next%3Dhttps%253A%252F%252Fm.facebook.com%252Fv3.1%252Fdialog%252Foauth%253Fredirect_uri%253Dhttp%25253A%25252F%25252Flocalhost%25253A8080%25252Fsignin%25252Ffacebook%2526state%253Dd8a641c9-8748-4a95-b603-737c956a99a9%2526scope%253Dpublic_profile%2526response_type%253Dcode%2526client_id%253D*****************%2526ret%253Dlogin%2526logger_id%253Dfb742942-3c31-c425-5749-882c6c0ef46c%26cancel_url%3Dhttp%253A%252F%252Flocalhost%253A8080%252Fsignin%252Ffacebook%253Ferror%253Daccess_denied%2526error_code%253D200%2526error_description%253DPermissions%252Berror%2526error_reason%253Duser_denied%2526state%253Dd8a641c9-8748-4a95-b603-737c956a99a9%2523_%253D_%26display%3Dtouch%26locale%3Den_GB%26logger_id%3Dfb742942-3c31-c425-5749-882c6c0ef46c; path=/; domain=.facebook.com; secure; httponly < Set-Cookie: sb=ECGKW6bOTMEfm2xndqZoMTNO; expires=Mon, 31-Aug-2020 05:18:08 GMT; Max-Age=63072000; path=/; domain=.facebook.com; secure; httponly < Vary: Accept-Encoding < X-FB-Debug: OnwhdsOlxvieobB7fQUJzvrM0ZsEsBT0GmQcjwly4PrW9W+LqTolqmH1tic3u2pfnvLrOHcG89yVOutAWdihVQ== < Date: Sat, 01 Sep 2018 05:18:08 GMT < Transfer-Encoding: chunked < Connection: keep-alive 

回答1:

After around three days today I finally found the solution.

First of all, The problem I was facing was because of this exception:

2018-09-01 10:05:50.679  INFO 7169 --- [io-8080-exec-10] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header  Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.  java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens     at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:428) ~[tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:684) ~[tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) [tomcat-embed-core-8.5.32.jar:8.5.32]     at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.32.jar:8.5.32]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.32.jar:8.5.32]     at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181] 

with a little search I found out facebook has began forcing HTTPS in callback urls.

After that, I had to fix call back url. The callback url that is set in application must match valid ones in facebook setting.

So I made this change:

@Bean     public ProviderSignInController providerSignInController(UsersConnectionRepository usersConnectionRepository, ConnectionFactoryLocator connectionFactoryLocator, FacebookSignInAdapter facebookSignInAdapter) throws Exception {         ((MongoUsersConnectionRepository) usersConnectionRepository)                 .setConnectionSignUp(facebookConnectionSignup);          ProviderSignInController providerSignInController = new ProviderSignInController(                 connectionFactoryLocator, usersConnectionRepository, facebookSignInAdapter);         List<ProviderSignInInterceptor<?>> list = new ArrayList<>();         list.add(new FacebookConnectionInterceptor());         providerSignInController.setSessionStrategy(new HttpSessionSessionStrategy());         providerSignInController.setSignInInterceptors(list);      // **IMPORTANT PART** >>     providerSignInController.setApplicationUrl("https://test.dropinmessenger.com");         providerSignInController.afterPropertiesSet();         return providerSignInController;     } 

after fixing the url (I could not use https on localhost, not sure even if this works on localhost), I had to provide valid callback_uri in facebook too:

The next error I faced was because I was not providing secret_proof or something close to that. The quickest fix was to turn it off from App Setting > Advanced > Require App Secret which does not seem to be safest solution.

ATTENTION Also make sure you are using latest spring-social-facebook dependency. these didn't work in version 1.1.1RELEASE, I used 2.0.3RELEASE.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!