.AspNetCore.Correlation. state property not found.

2019-08-26 03:20发布

I am using hybrid authentication flow with OIDC.

options.Events.OnRedirectToIdentityProvider = redirectContext =>
                      {
                          if (redirectContext.Request.Path.StartsWithSegments("/api"))
                          {
                              if (redirectContext.Response.StatusCode == (int)HttpStatusCode.OK)
                              {
                                  AuthenticationProperties  properties = new AuthenticationProperties();
                                  properties.RedirectUri = redirectContext.ProtocolMessage.RedirectUri;
                                  redirectContext.ProtocolMessage.State = options.StateDataFormat.Protect(properties);
                                  redirectContext.Response.StatusCode =   (int)HttpStatusCode.Unauthorized;
                                  redirectContext.Response.Headers["Location"] = redirectContext.ProtocolMessage.CreateAuthenticationRequestUrl();
                              }
                              redirectContext.HandleResponse();
                          }
                          return Task.CompletedTask;
                      };

As in above code I have manually set "state" property (which was suggested by ASP.Net core team, not in exact same way. refer below github issue link), but it is not working.

On callback, it gives warning as ".AspNetCore.Correlation. state property not found" and then it fails (as per below github bug) as "Error from RemoteAuthentication: Correlation failed.."

https://github.com/aspnet/AspNetCore/issues/7501

So what am I doing wrong. Because suggestion given in above bug is not possible, because it has some values which I don't have in this event.

what am I missing (or must do to complete this flow)?

2条回答
▲ chillily
2楼-- · 2019-08-26 03:31

state can be set as following. (Had to go through different properties of relevant and found.)

options.Events.OnRedirectToIdentityProvider = redirectContext =>
                      {
                          if (redirectContext.Request.Path.StartsWithSegments("/api"))
                          {
                              if (redirectContext.Response.StatusCode == (int)HttpStatusCode.OK)
                              {
                                  redirectContext.ProtocolMessage.State = options.StateDataFormat.Protect(redirectContext.Properties);
                                  redirectContext.Response.StatusCode =   (int)HttpStatusCode.Unauthorized;
                                  redirectContext.Response.Headers["Location"] = redirectContext.ProtocolMessage.CreateAuthenticationRequestUrl();
                              }
                              redirectContext.HandleResponse();
                          }
                          return Task.CompletedTask;
                      };
查看更多
劫难
3楼-- · 2019-08-26 03:34

I got it working by storing the original context.ProtocolMessage.State in context.Properties.Items:

var message = context.ProtocolMessage;
if (!string.IsNullOrEmpty(message.State))
{
    context.Properties.Items[OpenIdConnectDefaults.UserstatePropertiesKey] = message.State;
}
查看更多
登录 后发表回答