Итак, мой. NET Core WebApplication регистрирует пользователя через Azure AD, и у меня есть база данных с пользователями и их ролями.
Я уже создал OID C MiddleWare, чтобы добавить заявки из моей базы данных для пользователя, который пытается войти в систему.
Итак, поток:
- I войти с моей учетной записью 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;
},
};
});