当用户刚刚登录时,我需要做一些逻辑。记住当前会话的最后一个连接日期,然后将最后一个连接日期更新为Now
。
问题是我需要的事件应该在用户登录后仅发生一次。如果多次出现,真实“最后连接日期”将是用实际日期覆盖,不行......
我可以用它做什么?
我使用AzureAD身份验证。我使用了一个事件OnValidatePrincipal
,但这个事件多次发生......
是否有适合这种情况的事件?
我的代码:
public void ConfigureServices(IServiceCollection services) {
// [...]
services
.AddDistributedMemoryCache()
.AddSession(options =>
{ // Set a short timeout for easy testing.
options.Cookie.Name = ".MyApp.Session";
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
})
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.Events = new CookieAuthenticationEvents
{
OnSignedIn = context =>
{
Console.WriteLine("OnSignedIn, context=" + context);
return Task.FromResult(true);
},
OnValidatePrincipal = async context =>
{
var user = (ClaimsIdentity)context.Principal.Identity;
if (user.IsAuthenticated)
{
var mySingletonUser = context.HttpContext.RequestServices.GetService<IUser>();
var repository = context.HttpContext.RequestServices.GetService<ITableRepositories>();
var lastConnectedOn = DateTime.UtcNow;
var userId = user.Name;
var myUser = await repository.GetAsync<Connection>(userId);
context.HttpContext.Session.SetString(UserController.SessionKeyFormerConnetion, myUser.LastConnectedOn.ToLongDateString());
Claim isAdminClaim = new Claim("IsAdmin", myUser.IsAdmin.ToString(), ClaimValueTypes.Boolean);
user.AddClaim(isAdminClaim);
myUser.LastConnectedOn = DateTime.UtcNow;
var updatedUser = repository.InsertOrMergeAsync(new List<Connection> { myUser });
// update user from DB to display on the GUI
UpdateMySingletonUser(context.HttpContext.RequestServices, myUser);
Bellow是应用程序的调试日志,当用户注销然后再次登录时:
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/Account/SignOut
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/Account/SignOut
>>> OnValidatePrincipal
Microsoft.AspNetCore.Session.DistributedSession: Warning: Accessing expired session, Key:xxx-xxx-yyy-yyy
Microsoft.AspNetCore.Session.DistributedSession: Warning: Accessing expired session, Key:xxx-xxx-yyy-yyy
>>> New User updated
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.AccountController.SignOut (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.AccountController.SignOut (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.SignOutResult: Information: Executing SignOutResult with authentication schemes (Cookies, OpenIdConnect).
Microsoft.AspNetCore.Mvc.SignOutResult: Information: Executing SignOutResult with authentication schemes (Cookies, OpenIdConnect).
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies signed out.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies signed out.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Information: AuthenticationScheme: OpenIdConnect signed out.
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Information: AuthenticationScheme: OpenIdConnect signed out.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.AccountController.SignOut (MyApp) in 903.6182ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.AccountController.SignOut (MyApp) in 903.6182ms
Microsoft.AspNetCore.Session.DistributedSession: Information: Session started; Key:xxx-xxx-yyy-yyy, Id:yyyy-uuu-bbb-zzz
Microsoft.AspNetCore.Session.DistributedSession: Information: Session started; Key:xxx-xxx-yyy-yyy, Id:yyyy-uuu-bbb-zzz
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 1025.876ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 1025.876ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/signout-callback-oidc?state=xxx-yyy
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/signout-callback-oidc?state=xxx-yyy
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 21.9454ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 21.9454ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/Account/SignedOut
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/Account/SignedOut
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: (null).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: (null).
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult: Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Mvc.ChallengeResult: Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Information: AuthenticationScheme: OpenIdConnect was challenged.
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Information: AuthenticationScheme: OpenIdConnect was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.AccountController.SignedOut (MyApp) in 55.726ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.AccountController.SignedOut (MyApp) in 55.726ms
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 87.2328ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 87.2328ms 302
The thread 0x299c has exited with code 0 (0x0).
The thread 0x3b90 has exited with code 0 (0x0).
The thread 0x2714 has exited with code 0 (0x0).
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 POST http://localhost:23404/signin-oidc application/x-www-form-urlencoded 1878
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 POST http://localhost:23404/signin-oidc application/x-www-form-urlencoded 1878
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies signed in.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies signed in.
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 416.2449ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 416.2449ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/Account/SignedOut
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/Account/SignedOut
>>> OnValidatePrincipal
Microsoft.AspNetCore.Session.DistributedSession: Warning: Accessing expired session, Key:xxx-xxx-yyy-yyy
Microsoft.AspNetCore.Session.DistributedSession: Warning: Accessing expired session, Key:xxx-xxx-yyy-yyy
>>> New User updated
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.AccountController.SignedOut (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.AccountController.SignedOut (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.RedirectToActionResult: Information: Executing RedirectResult, redirecting to /.
Microsoft.AspNetCore.Mvc.RedirectToActionResult: Information: Executing RedirectResult, redirecting to /.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.AccountController.SignedOut (MyApp) in 14.6064ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.AccountController.SignedOut (MyApp) in 14.6064ms
Microsoft.AspNetCore.Session.DistributedSession: Information: Session started; Key:xxx-xxx-yyy-yyy, Id:yyyy-uuu-bbb
Microsoft.AspNetCore.Session.DistributedSession: Information: Session started; Key:xxx-xxx-yyy-yyy, Id:yyyy-uuu-bbb
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 89.5447ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 89.5447ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/
>>> OnValidatePrincipal
>>> New User updated
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.HomeController.Index (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.HomeController.Index (MyApp) with arguments ((null)) - ModelState is Valid
>>> Index HomeController, xuser = {MyApp.Data.Connection}
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor: Information: Executing ViewResult, running view at path /Views/Home/Index.cshtml.
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor: Information: Executing ViewResult, running view at path /Views/Home/Index.cshtml.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.HomeController.Index (MyApp) in 1264.8062ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.HomeController.Index (MyApp) in 1264.8062ms
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 1340.4051ms 200 text/html; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 1340.4051ms 200 text/html; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Theme
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Theme
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Progress
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Relevance
>>> OnValidatePrincipal
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Progress
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Record
>>> OnValidatePrincipal
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Record
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:23404/api/Relevance
>>> OnValidatePrincipal
>>> OnValidatePrincipal
>>> New User updated
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
>>> New User updated
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.ThemeController.Get (MyApp) with arguments ((null)) - ModelState is Valid
>>> New User updated
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
>>> New User updated
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.ThemeController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.ProgressController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.ProgressController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.RelevanceController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Controllers.RelevanceController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Api.Controllers.RecordController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method MyApp.Api.Controllers.RecordController.Get (MyApp) with arguments ((null)) - ModelState is Valid
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.ThemeController.Get (MyApp) in 167.0241ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.ThemeController.Get (MyApp) in 167.0241ms
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 297.0212ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 297.0212ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.ProgressController.Get (MyApp) in 129.5805ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.ProgressController.Get (MyApp) in 129.5805ms
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 314.6259ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 314.6259ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.RelevanceController.Get (MyApp) in 293.8995ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Controllers.RelevanceController.Get (MyApp) in 293.8995ms
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 491.3647ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 491.3647ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor: Information: Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Api.Controllers.RecordController.Get (MyApp) in 481.3165ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MyApp.Api.Controllers.RecordController.Get (MyApp) in 481.3165ms
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 675.4075ms 200 application/json; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 675.4075ms 200 application/json; charset=utf-8
The thread 0x4318 has exited with code 0 (0x0).
最有可能我需要记录它记录的时刻(两次,不幸的是:()
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myUser@myOrg.net.
哪个事件对应于该日志?