[英]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();
}
}
请尝试将SignIn Scheme
设置为IdentityConstants.ExternalScheme
:
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options => options.SignInScheme = IdentityConstants.ExternalScheme);
并将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
到最新版本或兼容版本并再次检查。
参考:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.