簡體   English   中英

open id "OnAuthorizatioCodeReceived" 中不會發生重定向

[英]Redirection doesn't happen in open id "OnAuthorizatioCodeReceived"

我使用 Azure ADB2C 進行身份驗證和授權,並使用 Open Id Connect 流程。 我需要將用戶重定向到應用程序主頁,並將檢索到的訪問令牌附加到主頁 url 作為來自“OnAuthorizationCodeReceived”的查詢參數。 但這不起作用。 下面是我的代碼。

通過這樣做,我打算從重定向 URL 中捕獲訪問令牌和 id 令牌。 這是一個單頁應用程序。 我嘗試過 MSAL.js,但它在瀏覽器兼容性方面存在問題,有時甚至在不同的身份提供者中也存在問題。 所以我決定從 c# 后端用戶打開 id

  public static class AzureAdB2CAuthenticationBuilderExtensions
{
    public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder)
        => builder.AddAzureAdB2C(_ =>
        {
        });

    public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder, Action<AzureAdB2COptions> configureOptions)
    {
        builder.Services.Configure(configureOptions);
        builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsSetup>();
        builder.AddOpenIdConnect();
        return builder;
    }

    public class OpenIdConnectOptionsSetup : IConfigureNamedOptions<OpenIdConnectOptions>
    {

        public OpenIdConnectOptionsSetup(IOptions<AzureAdB2COptions> b2cOptions)
        {
            AzureAdB2COptions = b2cOptions.Value;
        }

        public AzureAdB2COptions AzureAdB2COptions { get; set; }

        public void Configure(string name, OpenIdConnectOptions options)
        {
            options.ClientId = AzureAdB2COptions.ClientId;
            options.Authority = AzureAdB2COptions.Authority;
            options.UseTokenLifetime = true;
            //options.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/console/home");
            options.TokenValidationParameters = new TokenValidationParameters() { SaveSigninToken=true, NameClaimType = "name" };
            options.SaveTokens = true;
            options.Events = new OpenIdConnectEvents()
            {
                OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
                OnRemoteFailure = OnRemoteFailure,
                OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
                OnTokenValidated= OnTokenValidated,
                OnTokenResponseReceived= OnTokenResponseReceived
            };
        }

        public void Configure(OpenIdConnectOptions options)
        {
            Configure(Options.DefaultName, options);
        }

        public Task OnRedirectToIdentityProvider(RedirectContext context)
        {
            var defaultPolicy = AzureAdB2COptions.DefaultPolicy;
            if (context.Properties.Items.TryGetValue(AzureAdB2COptions.PolicyAuthenticationProperty, out var policy) &&
                !policy.Equals(defaultPolicy))
            {
                context.ProtocolMessage.Scope = OpenIdConnectScope.OpenIdProfile;
                context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken;
                context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.ToLower().Replace(defaultPolicy.ToLower(), policy.ToLower());
                context.Properties.Items.Remove(AzureAdB2COptions.PolicyAuthenticationProperty);
            }
            else if (!string.IsNullOrEmpty(AzureAdB2COptions.ApiUrl))
            {
                context.ProtocolMessage.Scope += $" offline_access {AzureAdB2COptions.ApiScopes}";
                context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.CodeIdToken;
            }
            return Task.FromResult(0);
        }

        public Task OnRemoteFailure(RemoteFailureContext context)
        {
            context.HandleResponse();
            // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page 
            // because password reset is not supported by a "sign-up or sign-in policy"
            if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("AADB2C90118"))
            {
                // If the user clicked the reset password link, redirect to the reset password route
                context.Response.Redirect("/Session/ResetPassword");
            }
            else if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("access_denied"))
            {
                context.Response.Redirect("/");
            }
            else
            {
                context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
            }
            return Task.FromResult(0);
        }

        public Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
        {

            // Use MSAL to swap the code for an access token
            // Extract the code from the response notification
            var code = context.ProtocolMessage.Code;

            string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
            try
            {
                List<string> apiScopes = new List<string>();

                AuthenticationResult result =  cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' ')).Result;

                //context.HandleResponse();
                context.HandleCodeRedemption(result.AccessToken, result.IdToken);
                context.Response.Redirect("http://localhost:8836/console/home?id_token="+result.IdToken+"&access_token="+result.AccessToken);
                return Task.FromResult(0);
                //context.HandleCodeRedemption(result.AccessToken, result.IdToken);

            }
            catch (Exception ex)
            {
                //TODO: Handle
                throw;
            }
        }

        public Task OnTokenValidated(TokenValidatedContext context)
        {
            try
            {
                return Task.FromResult(0);
            }
            catch (Exception ex)
            {

                throw;
            }
        }

        public Task OnTokenResponseReceived(TokenResponseReceivedContext context)
        {
            try
            {
                var cntxt = context;
                context.ProtocolMessage.RedirectUri = "/console/home";
                context.Response.Redirect("/Home/Error?message=test");
                return Task.FromResult(0);
            }
            catch (Exception ex)
            {

                throw;
            }
        }
    }
}

這是我的創業班

 public void ConfigureServices(IServiceCollection services)
    {

        services.Configure<AzureAdB2COptions>(Configuration.GetSection("Authentication:AzureAdB2C"));
        services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsSetup>();

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddAzureAdB2C(options => Configuration.Bind("Authentication:AzureAdB2C", options))
        .AddCookie();

        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        });

        services.AddMvc();

        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();
        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromHours(1);
            options.CookieHttpOnly = true;
        });
    }

你必須打電話

context.HandleResponse();

此方法處理來自 Auth 服務器的響應並獲取 JWT。

Microsoft Doc 上,您可以找到有關 OpenId Connect 的其他信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM