. NET Как НЕ авторизоваться, если предоставленный пользователь с OID C недоступен в базе данных - PullRequest
1 голос
/ 06 января 2020

Итак, мой. 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;
                },
            };
        });

1 Ответ

2 голосов
/ 06 января 2020

Вы можете переопределить обработку по умолчанию и обработать ответ самостоятельно:

// Send back to Login Page (with error message, maybe?)
ctx.HandleResponse();
ctx.Response.Redirect("/path/to/login");

Вызов HandleResponse сигнализирует, что мы хотим обработать ответ самостоятельно и следующие наборы вызовов до перенаправления. Существует несколько подходов к отправке сообщения об ошибке. Один из подходов заключается в предоставлении параметра строки запроса для URL входа в систему.

...