带有 Microsoft.Owin.Security.OpenIdConnect 和 AzureAD v 2.0 端点的自定义参数

Ben*_*tra 7 azure owin azure-active-directory openid-connect

我正在将 Azure AD 安全应用程序迁移到 v2.0 端点。

我需要将自定义参数传递给回复 uri。对于以前的 Azure AD 端点,我通过向回复 url 添加一个常用的查询参数来做到这一点。e.g. https://myserver.com/myredirect_uri?mycustomparamerter=myvalue

不幸的是,在端点 2.0 中,我收到一条错误消息,指出回复 uri 与注册的 uri 不匹配。当然,我的自定义参数值是动态的,我无法对其进行硬编码。

我希望利用OAUTH flow 中描述的“状态”参数。但是,I am using Microsoft.Owin.Security.OpenIdConnect看起来参数已经设置,所以我无法利用它。我正在使用一个基于 MVC 的流程实现,它看起来像这个示例

您能否提出一种解决方法,以便我的服务器在流程开始时设置的回复 url 中接收自定义参数?

Sac*_*aca 9

不确定是否有一种官方方法可以完成您的要求,但是您可以通过身份验证流程在技术上注入和提取额外值的一种方法是通过 OWIN 的通知。

在 Startup.Auth.cs 中,当您设置 OpenIdConnectAuthenticationOptions 时,您将添加以下内容:

app.UseOpenIdConnectAuthentication(
  new OpenIdConnectAuthenticationOptions
  {
    //...
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
      RedirectToIdentityProvider = OnRedirectToIdentityProvider,
      MessageReceived = OnMessageReceived
    },
  });
Run Code Online (Sandbox Code Playgroud)

并使用 RedirectToIdentityProvider 注入您的参数,大致如下:

private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
  var stateQueryString = notification.ProtocolMessage.State.Split('=');
  var protectedState = stateQueryString[1];
  var state = notification.Options.StateDataFormat.Unprotect(protectedState);
  state.Dictionary.Add("mycustomparameter", "myvalue");
  notification.ProtocolMessage.State = stateQueryString[0] + "=" + notification.Options.StateDataFormat.Protect(state);
  return Task.FromResult(0);
}
Run Code Online (Sandbox Code Playgroud)

然后使用 MessageReceived 提取它,如下所示:

private Task OnMessageReceived(MessageReceivedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
  string mycustomparameter;
  var protectedState = notification.ProtocolMessage.State.Split('=')[1];
  var state = notification.Options.StateDataFormat.Unprotect(protectedState);
  state.Dictionary.TryGetValue("mycustomparameter", out mycustomparameter);
  return Task.FromResult(0);
}
Run Code Online (Sandbox Code Playgroud)

您显然需要改进/强化这一点,但这应该会让您无法采用更好的整体方法。