c# - .NET 如果从 OIDC 提供的用户在数据库中不可用,如何不进行身份验证
问题描述
因此,我的 .NET Core WebApplication 正在通过 Azure AD 登录用户,并且我有一个包含用户及其角色的数据库。
我已经创建了 OIDC MiddleWare 以从我的数据库中为尝试登录的用户添加声明。
所以流程是:
- 我使用我的 AD 帐户登录
- 我得到电子邮件地址并在数据库中检查它的角色
- 现在,如果用户被阻止或未分配,登录应该会失败
所以我的问题是:当用户在数据库中不可用或被阻止时,有没有办法拒绝用户的身份验证?
我现在所做的是我设置了一个声明,如果该声明不可用,它将被重定向到拒绝访问页面(通过使用 AuthorizationPolicy),但我希望用户将被重定向到 Microsoft/AD 的登录页面(在最好的情况下带有消息)。
这有可能以某种方式实现吗?如果可以,怎么做?
这是我现在的代码:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => { Configuration.Bind("AzureAd", options); }
);
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireAssertion(context =>
{
Claim claim = context.User.Claims.First(claim => claim.Type == ClaimTypes.Expired);
return context.User.HasClaim(x => x.Type == ClaimTypes.Expired) &&
context.User.Claims.First(claim => claim.Type == ClaimTypes.Expired).Value
.Equals("false", StringComparison.OrdinalIgnoreCase);
})
.RequireClaim(ClaimTypes.Name)
.RequireClaim(ClaimTypes.Role)
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
// OIDC Middleware, to access the User's Claims while logging in through AzureAD
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Events = new OpenIdConnectEvents
{
OnRemoteFailure = ctx =>
{
ctx.Response.Redirect("/");
ctx.HandleResponse();
return Task.CompletedTask;
},
OnSignedOutCallbackRedirect = ctx =>
{
ctx.Response.Redirect("/");
ctx.HandleResponse();
return Task.CompletedTask;
},
OnTokenValidated = ctx =>
{
// Get the user's email
var email = ctx.Principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
// Query the database to get the role
using (var db = ctx.HttpContext.RequestServices.GetRequiredService<TracingContext>())
{
// Get the Users from the database, with the logged in email address (from Azure)
User user = db.Users.FirstOrDefault(u => u.UPN.Equals(email));
if (user != null)
{
user.LastLogin = DateTime.Now;
db.SaveChanges();
// Add claims
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role, user.Role.ToString()),
new Claim(ClaimTypes.Expired, (!user.IsActivated || user.IsBlocked).ToString())
};
// Save the claim
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
else
{
**// Send back to Login Page (with error message, maybe?)**
}
}
return Task.CompletedTask;
},
};
});
解决方案
您可以覆盖默认处理并自己处理响应:
// Send back to Login Page (with error message, maybe?)
ctx.HandleResponse();
ctx.Response.Redirect("/path/to/login");
对我们想要自己处理响应的信号的调用HandleResponse
以及以下调用设置重定向。有几种方法可以发送错误消息。一种方法是向登录 URL 提供查询字符串参数。
推荐阅读
- javascript - 在控制台中它可以工作,但在内容脚本中没有
- npm - 使用 npm 安装 web300 时出现问题
- vba - 使用回车在 Excel 单元格中创建换行符
- python - 无法使用 requests.get() 方法从 django rest api 获得响应
- youtube-data-api - Youtube data api V3 插入聊天消息错误
- javascript - 如何在 NPM 模块中呈现自定义视图?
- css - Webpack 构建成功,但 styles.css 文件样式未反映
- android - 如何使用 AndroidViewClient/dump 命令进行多设备转储?
- python - 逻辑回归:ValueError:未知标签类型:“连续”
- c++ - 如何告诉 VBO 处理给定的数据?(布模拟)