asp.net-mvc – 将参数传递给Azure Active Directory身份验证

我有一个ASP.Net MVC应用程序,Owin,我也使用Azure Active Directory身份验证.

我想在用户重定向到Azure AD身份验证页面时传递参数.因此,当用户登录注册时,我想将ProjectId(int)作为参数传递.

用户登录/注册重定向到我的应用程序后,我希望收到作为参数传递的ProjectId.

我怎样才能做到这一点?

编辑:添加代码

// The ACR claim is used to indicate which policy was executed
public const string AcrClaimType = "http://schemas.microsoft.com/claims/authnclassreference";
public const string PolicyKey = "b2cpolicy";
private const string OidcMetadataSuffix = "/.well-known/openid-configuration";

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions
    {
        // These are standard OpenID Connect parameters,with values pulled from web.config
        ClientId = ClientId,RedirectUri = RedirectUri,PostlogoutRedirectUri = RedirectUri,UseTokenLifetime = false,Notifications = new OpenIdConnectAuthenticationNotifications
        {
            AuthenticationFailed = AuthenticationFailed,RedirectToIdentityProvider = OnRedirectToIdentityProvider,SecurityTokenValidated = OnSecurityTokenValidated
        },Scope = "openid",ResponseType = "id_token",// The PolicyConfigurationManager takes care of getting the correct Azure AD authentication
        // endpoints from the OpenID Connect Metadata endpoint.  It is included in the PolicyAuthHelpers folder.
        ConfigurationManager = new PolicyConfigurationManager(
            string.Format(CultureInfo.InvariantCulture,AadInstance,Tenant,"/v2.0",OidcMetadataSuffix),new[] { SignUpPolicyId,SignInPolicyId,ProfilePolicyId }),// This piece is optional - it is used for displaying the user's name in the navigation bar.
        TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name"
        }
    };

    app.USEOpenIdConnectAuthentication(options);
}

private Task OnRedirectToIdentityProvider(
        RedirectToIdentityProviderNotification<OpenIdConnectMessage,OpenIdConnectAuthenticationOptions> notification)
{
    if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.logoutRequest)
    {
        var currentPolicy =
            notification.OwinContext.Authentication.AuthenticationResponseRevoke.AuthenticationTypes
                .FirstOrDefault(x => x.StartsWith("b2c"));
        notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.Split('?')[0];
        notification.ProtocolMessage.Parameters.Add("p",currentPolicy);
    }
    else
    {
        **// The value right now for the state is sort of "hijacked" and assigned by Microsoft**
        //notification.ProtocolMessage.Parameters["state"] = "OpenIdConnect.AuthenticationProperties=sRt-teBcxsd239viWo...... ";

        var currentPolicy = notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties
            .Dictionary[PolicyKey];
        notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.Split('?')[0];
        notification.ProtocolMessage.Parameters.Add("p",currentPolicy);
    }

    return Task.FromResult(0);
}

private async Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage,OpenIdConnectAuthenticationOptions> notification)
{
    await MyClass.CreatePrincipal(notification.AuthenticationTicket.Identity);
}

private Task AuthenticationFailed(
            AuthenticationFailedNotification<OpenIdConnectMessage,OpenIdConnectAuthenticationOptions> notification)
{
    notification.HandleResponse();
    notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
    return Task.FromResult(0);
}

解决方法

与Gaurav建议的相似,但增加了一些特殊的考虑因素.基本上,状态是由Owin中间件使用的,所以当你可以注入自己的东西时,你需要确保在Owin中间件试图使用它之前将其还原,否则你将获得auth错误.

这实际上是我回答了一个非常相似的问题:

Custom parameter with Microsoft.Owin.Security.OpenIdConnect and AzureAD v 2.0 endpoint

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

app.USEOpenIdConnectAuthentication(
  new OpenIdConnectAuthenticationOptions
  {
    //...
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
      RedirectToIdentityProvider = OnRedirectToIdentityProvider,MessageReceived = OnMessageReceived
    },});

并使用RedirectToIdentityProvider注入您的参数,类似于:

private static 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);
}

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

private static 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);
}

你显然需要改进/强化这个,但这应该让你去.

相关文章

项目要求通过网站上传大文件,比如视频文件,通过摸索实现了文件分片来上传,然后后台进行合并。 使用了...
安装新版本的Nginx(vim /etc/yum.repos.d/nginx.repo) [nginx-stable] name=nginx stable repo baseu...
什么是 SignalR&#160;ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功...
在Windows下使用Docker,我们选择Docker Desktop这个软件,非常方便。 ## Docker Desktop介绍及安装 Do...
项目开始设计的是运行在windows下,所以一开始采用的是windows服务模式来获取多媒体文件信息,后来要求...
银河麒麟高级服务器操作系统V10是针对企业级关键业务,适应虚拟化、云计算、大数据、工业互联网时代对主...