我的网络应用控制器上有[授权]属性,因此任何端点都会确保用户首先被重定向登录OAuth服务器(如果尚未登录)。
我现在想要在每次用户登录时开始将用户声明写入Web应用程序数据库。为此,我需要在每次用户成功登录/授权时在Web应用程序上运行一些代码。< / p>
我得到了一个线索,它涉及添加自定义中间件。
My 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;
});
}
... []
所以我的问题是:我需要添加哪些代码,以及在何处调用将包含自定义操作的方法?
答案 0 :(得分:6)
OpenIDConnectOptions
类具有Events
属性,适用于此类情况。此Events
属性(OpenIdConnectEvents
)具有OnTokenValidated
属性(Func<TokenValidatedContext, Task>
),您可以覆盖该属性,以便在令牌得到验证时得到通知。这是一些代码:
options.Events.OnTokenValidated = ctx =>
{
// Your code here.
return Task.CompletedTask;
};
在示例代码中,ctx
是TokenValidatedContext
,ultimately包含Principal
属性(ClaimsPrincipal
):您应该能够使用此属性获得您需要的索赔等财产,例如ctx.Principal.FindFirst(...)
。
正如@Brad在评论中提到的那样,每个请求都会调用OnTokenValidated
,并且(根据您自己的评论),不会包含您需要的UserInfo。为了实现这一点,您可以使用OnUserInformationReceived
,如下所示:
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
),正如我所说的那样带有评论的代码。
答案 1 :(得分:0)
你应该看看OpenIdConnectOptions.Events
。我没有举手示例,但这是挂钩OIDC中间件的地方。