捕获登录事件,以便我可以缓存其他用户信息 [英] Capturing login event so I can cache other user information
问题描述
我已经构建了一个Web应用程序.当我建立它时,我勾选了组织帐户"
I've built a web application. When I built it I ticked 'Organizational Accounts'
效果很好-我使用我的Office 365帐户登录,并且User.Identity.Name
包含电子邮件地址
It works well - I log in with my Office 365 account and User.Identity.Name
contains the email address
此应用程序是旧版ASP Classic应用程序的替代前端.该应用程序具有我需要使用的现有安全表.
This application is a replacement front end for an older ASP Classic app. The App has an existing security table that I need to use.
我想使用电子邮件地址在此表中查找记录以获取
I want to use the email address to look up a record in this table to get
-
用户的内部数据库密钥(因此我可以在数据库调用中使用它)
The internal database key for the user (so I can use it in database calls)
用户的安全级别(授权)
The security level (authorisation) for the user
我想在通过身份验证后立即进行查找,并将这两个值保存到Session
中以供以后参考
I want to look this up as soon as I am authenticated and save these two values to Session
to refer to later
我有一个现有的方法来执行所有这些查找和缓存.我实际上是通过_LoginPartial.cshtml
视图调用它来使其工作的,但是显然从视图触发这种事情是不正确的
I have an existing method that does all of this lookup and caching. I actually got it working by calling it from the _LoginPartial.cshtml
view but clearly it is incorrect to be triggering this kind of thing from a view
这是用于查找和缓存用户信息的代码.目前,该文件位于AccountController.cs
中,但不一定必须
Here's the code to look up and cache user info. For now this is in AccountController.cs
but it doesn't have to be
private Boolean GetAdditionalUserInfo()
{
// if authentication info is saved, don't go find it
if (Session["UID"] != null) return true;
// get the db employee id from the database and save it to the session
var r = (
from e in db.Employees
where e.Email == User.Identity.Name
select new
{
e.Emp_ID,
e.Group_ID
}
).SingleOrDefault();
if ((r == null) || (r.Group_ID == (int)Role.Inactive))
{
// couldn't find record or inactive
return false;
}
// Update last login datetime
Employee ell = db.Employees.Find(r.Emp_ID);
ell.LastLogin = DateTime.Now;
db.SaveChangesAsync();
// Save user details to the session
Session["UID"] = r.Emp_ID;
// TBD: Investigate "CLAIMS" - this should probably be a claim
Session["Role"] = r.Group_ID;
return true;
}
我认为对User.Identity.Name
的引用会触发登录过程,因此我可以尝试在启动时调用它(我不知道执行此操作的正确方法),或者我认为正确的做法是使用OnAuthentication
方法调用它,并将其链接起来,我应该将函数的名称传递给OnAuthenticated
属性.这是方法和属性的两个链接:
I think the reference to User.Identity.Name
triggers the login process so I could either just try and call this at startup (I don't know the correct way to do this), or I think the proper thing to do is to call this using the OnAuthentication
method, and to link it up I should pass the name of my function to the OnAuthenticated
property. Here's two links to the method and property:
https://msdn.microsoft.com/zh-CN/library/system.web.mvc.controller.onauthentication(v=vs.118).aspx
但是我不得不说,OO编程不是我的事,我无法从这些页面中了解如何使用它们或将它们放入哪个类.
此 page 表示它需要进入Startup.Auth.cs
,但我的Startup.Auth.cs
看起来并不像那个.这是我大部分的Startup.Auth.cs
,大部分是在我一开始勾选"organistical"时自动生成的. (顺便提一下,app.UseKentorOwinCookieSaver();
是我的下一个挑战,因为显然组织登录不适用于Session
,您相信吗!)
This page implies it needs to go into Startup.Auth.cs
but my Startup.Auth.cs
looks nothing like that one. Here is most of my Startup.Auth.cs
which was mostly autogenerated when I ticked 'organisational' at the start. (On a side note, app.UseKentorOwinCookieSaver();
is my next challenge because apparently organisational login doesn't work with Session
can you believe it!!!)
有人可以帮我添加所需的代码来调用GetAdditionalUserInfo()
吗?登录后?或者,也可以确认我可以在启动时打电话给它,并提出正确的操作方法.
Can anyone help me add required code to call GetAdditionalUserInfo()
? after login? Or alternatively confirm that I can just call this at startup, and suggest the correct way to do it.
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
//private static string authority = aadInstance + tenantId;
// to make this multi tenant, use common endpoint, not the tenant specific endpoint
private static string authority = aadInstance + "common";
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(
CookieAuthenticationDefaults.AuthenticationType);
// https://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser
app.UseKentorOwinCookieSaver();
app.UseCookieAuthentication(
new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
TokenValidationParameters = new TokenValidationParameters
{
// If you don't add this, you get IDX10205
// from here http://charliedigital.com/2015/03/14/adding-support-for-azure-ad-login-o365-to-mvc-apps/
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = ctx =>
{
bool isAjaxRequest = (ctx.Request.Headers != null && ctx.Request.Headers["X-Requested-With"] == "XMLHttpRequest");
if (isAjaxRequest)
{
ctx.Response.Headers.Remove("Set-Cookie");
ctx.State = NotificationResultState.HandledResponse;
}
return System.Threading.Tasks.Task.FromResult(0);
}
}
});
}
}
推荐答案
In article The OWIN OpenID Connect Middleware you can find detailed explanation how you could use Notifications
. In you case you should subscribe to SecurityTokenValidated
:
RedirectToIdentityProvider = ctx => {...},
SecurityTokenValidated = (context) =>
{
string userID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
// Here you can retrieve information from Database. Let's say you get r.Group_ID.
var role = r.Group_ID;
// You can now add it to Identity and no need to use session.
Claim roleClaim = new Claim(
"http://nomatterwhatyouput/role",
role,
ClaimValueTypes.[RoleType],
"LocalAuthority");
context.AuthenticationTicket.Identity.AddClaim(roleClaim);
// Do same for all values you have. Remember to set unique claim URL for each value.
return Task.CompletedTask;
},
然后您可以按照该文章中所述在操作中检索这些值:
And then you can retrieve those values in you actions as mentioned in that article:
public ActionResult Index()
{
var role = ClaimsPrincipal.Current.FindFirst("http://nomatterwhatyouput/role");
return View();
}
这篇关于捕获登录事件,以便我可以缓存其他用户信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!