FusionAuth Google 登录抛出错误后的回调

Callback after Google login throwing error in FusionAuth

我们将 FusionAuth (1.7.4) 登录屏幕与我们的 SPA 一起使用,并在 FusionAuth 中将 Google 配置为 IdP 并设置 Google OAuth 客户端凭据,如下所述:https://fusionauth.io/docs/v1/tech/identity-providers/google

当用户单击 Google 登录按钮并在 Google 上进行身份验证时,浏览器会发送到 https://ident.<mydomain>/oauth2/callback,这会显示 FusionAuth UI 'missing_redirect_url'。

回调的完整 URL 如下所示(为清楚起见,此处用 {{variables}} 缩写):

https://ident.{{SPA_domain}}/oauth2/callback?token={{tokenstring}}&identityProviderId={{fusion_IdP_Id}}&state=client_id%3D{{SPA_App_ID}}%26metaData.device.name%3DMac%2520Safari%26metaData.device.type%3DBROWSER%26nonce%3D%26redirect_uri%3Dhttps%253A%252F%252Fapi.proxy.{{SPA_domain}}%252F{{SPA_name}}%252FOAuthLoginFlowHandler%253Fclient_id%253D {{SPA_App_ID}}%26response_type%3Dcode%26scope%3D%26state%3Dexample%26timezone%3DAustralia%252FSydney

FusionAuth 声称缺少的 redirect_uri 是双重编码的,它存在于 'state' 参数后面,缺少 client_id 之前的值和后续 & 分隔符。

如果我们手动更正状态参数,则回调会生成“500 内部服务器错误”。 google 正在将令牌发送回我们的融合 idp。我们不确定 Fusion 如何处理该令牌并将用户重定向到应用程序。我们认为 google 会发送 code 到融合,融合会将该代码交换为令牌。我们为 Google IdP 启用了调试,但没有获得任何有用的日志记录。

如果可以改进社交登录实现文档以解释完整的流程和不同的实现技术,那将大有帮助。

FusionAuth 日志:

Sep 07, 2019 9:20:05.108 PM ERROR io.fusionauth.app.primeframework.error.ExceptionExceptionHandler - An unhandled exception was thrown
java.lang.NullPointerException: null
    at org.primeframework.mvc.parameter.el.Expression.setCurrentValue(Expression.java:93)
    at org.primeframework.mvc.parameter.el.DefaultExpressionEvaluator.setValue(DefaultExpressionEvaluator.java:129)
    at io.fusionauth.app.action.oauth2.CallbackAction.decodeAndRestoreState(CallbackAction.java:158)
    at io.fusionauth.app.action.oauth2.CallbackAction.get(CallbackAction.java:85)
    at sun.reflect.GeneratedMethodAccessor432.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.primeframework.mvc.util.ReflectionUtils.invoke(ReflectionUtils.java:436)
    at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.execute(DefaultActionInvocationWorkflow.java:84)
    at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.perform(DefaultActionInvocationWorkflow.java:64)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.validation.DefaultValidationWorkflow.perform(DefaultValidationWorkflow.java:47)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.security.DefaultSecurityWorkflow.perform(DefaultSecurityWorkflow.java:60)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.parameter.DefaultPostParameterWorkflow.perform(DefaultPostParameterWorkflow.java:50)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.content.DefaultContentWorkflow.perform(DefaultContentWorkflow.java:52)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:57)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:102)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:58)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.message.DefaultMessageWorkflow.perform(DefaultMessageWorkflow.java:45)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:126)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.workflow.StaticResourceWorkflow.perform(StaticResourceWorkflow.java:97)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.parameter.RequestBodyWorkflow.perform(RequestBodyWorkflow.java:89)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:57)
    at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43)
    at org.primeframework.mvc.workflow.DefaultMVCWorkflow.perform(DefaultMVCWorkflow.java:91)
    at org.primeframework.mvc.workflow.DefaultWorkflowChain.continueWorkflow(DefaultWorkflowChain.java:44)
    at org.primeframework.mvc.servlet.FilterWorkflowChain.continueWorkflow(FilterWorkflowChain.java:50)
    at org.primeframework.mvc.servlet.PrimeFilter.doFilter(PrimeFilter.java:84)
    at com.inversoft.maintenance.servlet.MaintenanceModePrimeFilter.doFilter(MaintenanceModePrimeFilter.java:59)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.inversoft.servlet.UTF8Filter.doFilter(UTF8Filter.java:27)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

注意: 我们在常规登录流程中使用 authorization_code 授权。所以我们想对社交登录重用相同的内容

FusionAuth 在从 Google 返回时解码状态参数的方式存在错误。

redirect_uri 包含带有请求参数(例如 https://acme.com/oauth/callback?client_id=b3bef9c1-ba42-414b-aca1-8d30c9252d36)的 URL 时,就会显示该错误。

这将在即将发布的 1.8.1 或 1.9.0 版本中修复。同时,解决方法是使用 URL 段(如果可能的话)或使用 state 参数来确保您在重定向 URL 上获得必要的信息。

感谢举报!