繁体   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