ASP. NET Core MVC Код запуска AzureAD после успешного входа в систему - PullRequest
0 голосов
/ 05 августа 2020

Я использую. У меня есть проверка подлинности в AzureAD, настроенная с использованием OpenID Connect с приложением ASP. NET Core 2.2 MVC. Я хочу иметь возможность регистрировать информацию о пользователе сразу после успешного входа в приложение.

В приведенном ниже коде я использую событие options.Events.OnTicketReceived для добавления требований ролей из внешней базы данных в удостоверение. после успешной аутентификации в AzureAD. Однако мое исследование показывает, что событие OnTicketReceived вызывается прямо до , когда пользователь вошел в систему, то есть прямо перед созданием локального повара ie и аутентификации пользователя в приложении. (Источник: post1 , post2 ). Это будет означать, что пользователь еще не прошел аутентификацию в приложении, и я не знаю, будет ли после события OnTicketReceived гарантирована аутентификация пользователя.

Все это заставляет меня задуматься: правильно регистрировать мое сообщение "пользователь вошел в систему" при событии OnTicketReceived или есть другой способ сделать это? Я также не уверен, что я должен регистрировать эту информацию в Startup.cs.

Startup.cs> Метод ConfigureServices

public void ConfigureServices(IServiceCollection Services)
{
    //https://weblog.west-wind.com/posts/2017/dec/12/easy-configuration-binding-in-aspnet-core-revisited
    IAppSettings config = new AppSettings();
    Configuration.Bind("AppSettings", config);

    Services.AddMvc();
    Services.AddSingleton(config);
    
    //bunch of service dependencies here...

    Services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    Services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
        .AddAzureAD(options =>
        {
            options.Instance = config.AzureAD.Instance;
            options.Domain = config.AzureAD.Domain;
            options.TenantId = config.AzureAD.TenantId; //TenantID is set to "organizations"
            options.ClientId = config.AzureAD.ClientId; //the ID of the registered app in AzureAD
            options.CallbackPath = config.AzureAD.CallbackPath;
        });

    Services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
    {
        options.UseTokenLifetime = false;
        options.Authority = options.Authority + "/v2.0/"; //Microsoft identity platform

        options.TokenValidationParameters.ValidateIssuer = true;
        options.TokenValidationParameters.ValidIssuers = config.AzureAD.Organizations; //List<string> of allowed organizations
        // https://stackoverflow.com/questions/49469979/azure-ad-b2c-user-identity-name-is-null-but-user-identity-m-instance-claims9
        // https://stackoverflow.com/questions/54444747/user-identity-name-is-null-after-federated-azure-ad-login-with-aspnetcore-2-2
        options.TokenValidationParameters.NameClaimType = "http://schemas.microsoft.com/identity/claims/objectidentifier";

        //Code below is to add claims during login (we add roles from db): https://stackoverflow.com/questions/51965665/adding-custom-claims-to-claimsprincipal-when-using-addazureadb2c-in-mvc-core-app
        //some discussion about this here: https://stackoverflow.com/questions/59564952/net-core-add-claim-after-azuerad-authentication
        //and here: https://stackoverflow.com/questions/52727146/net-core-2-openid-connect-authentication-and-multiple-identities
        options.Events.OnTicketReceived = context =>
        {
            string userEmail = context.Principal.FindFirstValue(ClaimTypes.Email);
            //I get an instance of UserAccess service so I can check termination status and get the roles by email.
            IUserAccess userAccess = context.HttpContext.RequestServices.GetService<IUserAccess>();
            
            bool terminated = userAccess.GetUserTerminationStatusByUserEmail(userEmail, config.ConnectionString);
            if (terminated == false)
            {
                ClaimsIdentity claimsIdentity = (ClaimsIdentity)context.Principal.Identity;
                List<string> roles = userAccess.GetUserRolesByUserEmail(userEmail, config.ConnectionString);
                foreach (var role in roles)
                {
                    claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role));
                }
            }

            return Task.CompletedTask;
        };
    });

    Services.Configure<CookieAuthenticationOptions>(AzureADDefaults.CookieScheme, options =>
    {
        options.AccessDeniedPath = "/UserAccess/NotAuthorized";
        options.LogoutPath = "/UserAccess/SignOut";
        options.ExpireTimeSpan = TimeSpan.FromMinutes(config.AzureAD.TimeoutInMinutes);
        options.SlidingExpiration = true;
    });
}

Для входа в систему и выхода из системы я использовать существующие функции из пакета Microsoft.AspNetCore.Authentication.AzureAD.UI NuGet и вызывать их в моих представлениях следующим образом:

<!-- to sign out -->
<a asp-area="AzureAD" asp-controller="Account" asp-action="SignOut">Sign out</a>

<!-- to sign in -->
<a asp-area="AzureAD" asp-controller="Account" asp-action="SignIn">Sign in with Microsoft</a>

1 Ответ

0 голосов
/ 07 августа 2020

Как вы сказали, OnTicketReceived вызывается при нажатии кнопки входа в систему, но вы хотите, чтобы вход был успешным.

Вы увидите вход в систему и Журналы аудита из Azure AD на портале.

enter image description here

Sign-ins – Information about the usage of managed applications and user sign-in activities.

Audit logs - Audit logs provide system activity information about users and group management, managed applications, and directory activities.

So you don't need to add logs using NLog, the sign-in logs are automatically stored. For more details about listing sign-ins, see здесь .

Пример кода:

// Read application settings from appsettings.json (tenant ID, app ID, client secret, etc.)
AppSettings config = AppSettingsFile.ReadFromJsonFile();

// Initialize the client credential auth provider
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
    .Create(config.AppId)
    .WithTenantId(config.TenantId)
    .WithClientSecret(config.ClientSecret)
    .Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

// Set up the Microsoft Graph service client with client credentials
GraphServiceClient graphClient = new GraphServiceClient(authProvider);

// status/errorCode eq '0' means sign-in success
var signIns = await graphClient.AuditLogs.SignIns
    .Request()
    .Filter("status/errorCode eq '0'")
    .GetAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...