在Asp.net MVC中与Okta集成时,可能会出现在SigninManager.SignIn后Okta Claims被替换的问题。下面是一个可能的解决方案,包含代码示例:
public void ConfigureServices(IServiceCollection services)
{
// 添加Okta身份验证服务
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OktaDefaults.MvcAuthenticationScheme;
})
.AddCookie()
.AddOktaMvc(new OktaMvcOptions()
{
OktaDomain = Configuration["Okta:OktaDomain"],
ClientId = Configuration["Okta:ClientId"],
ClientSecret = Configuration["Okta:ClientSecret"]
});
// 其他配置代码...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// 其他配置代码...
// 启用身份验证中间件
app.UseAuthentication();
// 其他配置代码...
}
[HttpPost]
[AllowAnonymous]
public async Task Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
// 获取用户声明
var user = await _userManager.FindByEmailAsync(model.Email);
var claims = await _userManager.GetClaimsAsync(user);
// 添加Okta声明
claims.Add(new Claim("okta:email", model.Email));
// 更新用户声明
await _userManager.ReplaceClaimAsync(user, new Claim(ClaimTypes.Email, model.Email), new Claim(ClaimTypes.Email, model.Email));
await _userManager.AddClaimsAsync(user, claims);
// 登录
await _signInManager.SignInAsync(user, isPersistent: false);
// 返回到之前的URL
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(nameof(HomeController.Index), "Home");
}
}
// 其他登录失败的处理代码...
}
// 其他处理代码...
}
通过在登录操作中获取用户声明并添加Okta声明,然后使用ReplaceClaimAsync方法更新用户声明,可以解决在SigninManager.SignIn后Okta Claims被替换的问题。这样,Okta的声明就会保留下来,并与AspNet Identity的声明一起使用。