捕获登录事件,以便我可以缓存其他用户信息 [英] Capturing login event so I can cache other user information

查看:149
本文介绍了捕获登录事件,以便我可以缓存其他用户信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经构建了一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆