Перехватить действие авторизации ядра asp.net для выполнения настраиваемого действия после успешной авторизации

У меня есть атрибут [Authorize] на моем контроллере веб-приложения, поэтому любые попадания в конечные точки гарантируют, что пользователь сначала будет перенаправлен для входа на сервер OAuth (если он еще не вошел в систему).

Теперь я хочу начать писать заявки пользователей в базу данных веб-приложения каждый раз, когда пользователь входит в систему. Для этого мне нужно иметь некоторый код, который запускается в веб-приложении каждый раз, когда пользователь успешно входит в систему / авторизуется.

Мне дали понять, что это включает добавление специального промежуточного программного обеспечения.

Мой код Startup ConfigureServices в настоящее время выглядит следующим образом:

public class Startup
{
    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        Env = env;
    }

    public IHostingEnvironment Env { get; }
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddMvc();

        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            options.Cookie.HttpOnly = true;
        });

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.SignInScheme = "Cookies";
                options.Authority = Configuration["auth:oidc:authority"];                    

                options.RequireHttpsMetadata = !Env.IsDevelopment();
                options.ClientId = Configuration["auth:oidc:clientid"];
                options.ClientSecret = Configuration["auth:oidc:clientsecret"];
                options.ResponseType = "code id_token"; 

                options.Scope.Add(Configuration["auth:oidc:clientid"]);
                options.Scope.Add("offline_access");

                options.GetClaimsFromUserInfoEndpoint = true;
                options.SaveTokens = true;

            });

    }

... []

Итак, мой вопрос: какой код мне нужно добавить и где, чтобы вызвать метод, который будет содержать мое настраиваемое действие?


person egmfrs    schedule 06.04.2018    source источник


Ответы (2)


_1 _ класс имеет Events свойство, которое предназначено для подобных сценариев. Это свойство Events ( OpenIdConnectEvents) имеет _ 5_ свойство (Func<TokenValidatedContext, Task>), которое вы можете перезаписать, чтобы получать уведомления, когда токен, в общем, проверен. Вот код:

options.Events.OnTokenValidated = ctx =>
{
    // Your code here.
    return Task.CompletedTask;
};

В примере кода ctx - это _ 9_, который в конечном итоге содержит свойство Principal (ClaimsPrincipal): вы должны иметь возможность использовать это свойство для получения утверждений и т. д., которые вам нужны, например, ctx.Principal.FindFirst(...).

Как упоминает @Brad в комментариях, OnTokenValidated вызывается для каждого запроса и (на основе вашего собственного комментария) не будет содержать нужную вам информацию о пользователях. Для этого вы можете использовать _ 14_, вот так:

options.Events.OnUserInformationReceived = ctx =>
{
    // Here, ctx.User is a JObject that should include the UserInfo you need.
    return Task.CompletedTask;
};

ctx в этом примере - это UserInformationReceivedContext: он по-прежнему включает свойство Principal, но также имеет свойство User (JObject), как я указал в коде с комментарием.

person Kirk Larkin    schedule 06.04.2018
comment
Событие OnUserInformationReceived лучше подходит для нужд OP. Он выполняется один раз при успешном входе в систему. Предоставленное вами событие выполняется по каждому запросу. - person Brad; 06.04.2018
comment
Если вы используете Azure B2C, этот ответ показывает, как получить доступ к событиям OIDC: stackoverflow.com/a/58515372/2608 - person Sean Kearon; 14.03.2020

Вам следует посмотреть на _ 1_. У меня нет примера, но это место, чтобы подключиться к промежуточному программному обеспечению OIDC.

person kͩeͣmͮpͥ ͩ    schedule 06.04.2018