加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

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

发布时间:2020-12-16 00:17:30 所属栏目:asp.Net 来源:网络整理
导读:我有一个ASP.Net MVC应用程序,Owin,我也使用Azure Active Directory身份验证. 我想在用户重定向到Azure AD身份验证页面时传递参数.因此,当用户登录或注册时,我想将ProjectId(int)作为参数传递. 在用户登录/注册并重定向到我的应用程序后,我希望收到作为参数
我有一个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);
}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读