簡體   English   中英

具有多種身份驗證方案的 Asp Net Core。 將 Azure AD 集成到 Indentity

[英]Asp Net Core with multiple authentication schemes. Integrate Azure AD into Indentity

我有一個 web 應用程序,它允許用戶使用本地身份驗證登錄和注冊(使用 JWT 身份驗證方案),還允許用戶登錄他們的 azure 活動目錄帳戶(使用 OpenIdConnect 方案)。 我將使用 azure 活動目錄的日志記錄視為外部登錄,但是,當我嘗試獲取GetExternalLoginInfoAsync()時,我不斷收到 null 響應

以下是我的設置:

services.AddAuthentication(options =>
            {
                options.DefaultScheme = "JWT_OR_COOKIE";
                options.DefaultChallengeScheme = "JWT_OR_COOKIE";
            })            
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            // for azure active directory
            .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {
                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;                    
                options.Authority = config["authority"];
                options.ClientId = config["clientId"];
                options.ClientSecret = config["clientSecret"];
                options.ResponseType = "code";
                options.SaveTokens = true;
            })
            // for local login
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["TokenKey"])),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };
                options.RequireHttpsMetadata = env.IsProduction();
            })                
            .AddPolicyScheme("JWT_OR_COOKIE", "JWT_OR_COOKIE", options =>
            {
                // runs on each request
                options.ForwardDefaultSelector = context =>
                {
                    // filter by auth type
                    string authorization = context.Request.Headers[HeaderNames.Authorization];
                    if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
                        return JwtBearerDefaults.AuthenticationScheme;

                    // otherwise always check for cookie auth                        
                    return OpenIdConnectDefaults.AuthenticationScheme;
                };
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
            });

我的 controller:

[HttpGet("login")]
        [AllowAnonymous]
        public async Task<IActionResult> ExternalLogin([FromQuery] string returnUrl)
        {            
            var scheme = OpenIdConnectDefaults.AuthenticationScheme;            

            var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });

            return Challenge(new AuthenticationProperties
            {
                RedirectUri = redirectUrl
            }, scheme);

        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
        {
            var acccessToken = await HttpContext.GetTokenAsync("access_token"); // <== this works

            var info = await _signInManager.GetExternalLoginInfoAsync(); // <=== this is null, and I don't know what I did wrong in here !!!

            var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);

            if (result.Succeeded)
            {
                // update any authentication process
                await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
                return LocalRedirect(returnUrl);
            }
            else
            {
                // do not have account yet
                return Ok();
            }


        }
  1. 請嘗試將SignIn Scheme設置為IdentityConstants.ExternalScheme

     services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options => options.SignInScheme = IdentityConstants.ExternalScheme);
  2. 並將cookie scheme to null

services.AddAuthentication()
   .AddMicrosoftIdentityWebApp(Configuration, cookieScheme: null);

就像是:-

 options => {
    ...
    options.ClientId = config.ClientId;
    options.TenantId = config.TenantId;
    options.CallbackPath = config.CallbackPath;
    options.SignInScheme = IdentityConstants.ExternalScheme;
    options.SignOutScheme = IdentityConstants.ExternalScheme;
   ...
  },
  openIdConnectScheme: idp.LoginProvider,
  cookieScheme: null 
);

在某些情況下,還可以嘗試upgrading asp.net core到最新版本或兼容版本並再次檢查。

參考:

  1. signInManager.GetExternalLoginInfoAsync() 始終返回 null。GitHub
  2. asp.net 核心 - _signInManager.GetExternalLoginInfoAsync() 始終返回 null 並打開 id 到 azure 廣告 - 代碼日志

暫無
暫無

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

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