Asp.net-Mvc

將參數傳遞給 Azure Active Directory 身份驗證

  • September 7, 2020

我有一個 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 中間件嘗試使用它之前將其還原,否則您將收到身份驗證錯誤。

這實際上是我對一個非常相似的問題的回答:

帶有 Microsoft.Owin.Security.OpenIdConnect 和 AzureAD v 2.0 端點的自定義參數

在 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);
}

你顯然需要改進/加強這一點,但這應該能讓你繼續前進。

引用自:https://stackoverflow.com/questions/37770989