如何在aspnet身份中进行会话管理?

问题描述 投票:17回答:3

我正在使用 Asp.net身份认证 对于 登录、注册、忘记密码 等,源码取自下面这个链接。

http:/www.asp.netmvcoverviewsecuritycreate-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset

http:/www.asp.netidentityoverviewfeatures-apiaccount-confirmation-and-password-recovery-with-aspnet-identity.

现在,我有一个表,是UserMaster,在注册过程中,我要求以下字段。全名,EmailId,密码,联系电话,性别。.

我的用户管理包含以下字段。Id,FullName,EmailId,ContactNumber,Gender(性别)。

现在,当用户提交注册表时,这些全名、EmailId、联系电话、性别将被保存在以下信息中 用户管理 连同 电子邮件,密码将保存在AspnetUser中。.

我的注册方法 与上述2个链接中提供的相同。

在这里你可能会注意到,有 我的UserMaster和AspnetUser之间没有关系 因此,在登录时,当用户输入他的电子邮件ID登录时,我将使用这种方法。await SignInManager.PasswordSignInAsync 来验证用户,如果这个方法返回成功,那么我将做的是使用这个电子邮件ID和检查这个电子邮件在我的UserMaster和匹配将被发现,我将从UserMaster获取该UserId和存储在会话和使用贯穿我的应用程序在我的登录方法,像下面。

 public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
            {
                if (!ModelState.IsValid)
                {
                    return View(model);
                }

                // This doesn't count login failures towards account lockout
                // To enable password failures to trigger account lockout, change to shouldLockout: true
                var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
                switch (result)
                {
                    case SignInStatus.Success:
                  using (var context = new MyEntities())
                        {
                            var fetchUSerId = context.UserMaster.Where(t => t.Email == model.Email).Select(t=>t.UserId).SingleOrDefault();
                            Session["UserId"] = fetchUSerId;
                        }
                        return RedirectToLocal(returnUrl);
                    case SignInStatus.LockedOut:
                        return View("Lockout");
                    case SignInStatus.RequiresVerification:
                        return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                    case SignInStatus.Failure:
                    default:
                        ModelState.AddModelError("", "Invalid login attempt.");
                        return View(model);
                }
            }

我说的是在我的登录方法。

 case SignInStatus.Success:
                      using (var context = new MyEntities())
                            {
                                var fetchUSerId = context.UserMaster.Where(t => t.Email == model.Email).Select(t=>t.UserId).SingleOrDefault();
                                Session["UserId"] = fetchUSerId;
                            }

这是一个合适的方式,还是一个更好的方式,我想存储整个用户对象,而不仅仅是存储User Id。

谁能告诉我如何使用aspnet identity来实现这个目标?

c# asp.net-mvc asp.net-identity owin
3个回答
29
投票

由于你使用的是Asp.Net Identity,你想把与会话相关的东西存储为索赔。 这很容易用自定义的索赔来扩展。

作为一个旁观者,我认为你最好简单地扩展一下 ApplicationUser 以保存额外数据,详见 此处.

也就是说,这里有一个完整的例子来说明如何在您的应用程序中添加自定义索赔类型。

第一步 - 定义一个或多个自定义索赔类型,以保存您的附加信息。

public static class CustomClaimTypes
{
    public const string MasterFullName = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/masterfullname";
    public const string MasterUserId = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/masteruserid";
}

索赔类型只是一个唯一的字符串,用来标识特定的索赔。 在这里,我们只是使用类似于内置的索赔类型的格式。

第二步 - 在签到过程中,为自定义的索赔类型设置值。

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

    //Fetch data from the UserMaster table 
    var userdata = GetdatafromUserMaster();

    //Using the UserMaster data, set our custom claim types
    identity.AddClaim(new Claim(CustomClaimTypes.MasterUserId, userdata.UserId));
    identity.AddClaim(new Claim(CustomClaimTypes.MasterFullName, userdata.FullName));

    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

注:我们使用的是自定义索赔类型,因此我们保留了现有的 NameIdentifierName 声称,因此可以轻松地从Asp.Net Identity中访问身份信息。 我们的定制 UserMaster 表。

第三步 - 添加扩展方法到 IIdentity 这样我们就可以轻松地访问我们的自定义索赔数据

public static class IdentityExtensions
{
    public static string GetMasterUserId(this IIdentity identity)
    {
        if (identity == null)
            return null;

        return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.MasterUserId);
    }

    public static string GetMasterFullName(this IIdentity identity)
    {
        if (identity == null)
            return null;

        return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.MasterFullName);
    }

    internal static string FirstOrNull(this ClaimsIdentity identity, string claimType)
    {
        var val = identity.FindFirst(claimType);

        return val == null ? null : val.Value;
    }
}

这里没有什么花哨的东西。 我们只是投 IIdentity 作为 ClaimsIdentity 然后返回给定的第一个权利要求的值。CustomClaimType 我们发现,或者我们返回 null 如果一个索赔不存在。

第四步 - 现在,我们可以在视图或控制器中轻松访问我们的自定义索赔数据。 假设你想使用来自于你的 UserMaster 列表 ApplicationUser? 你现在可以这样做了。

<ul class="nav navbar-nav navbar-right">
    <li>
        @Html.ActionLink("Hello " + User.Identity.GetMasterFullName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
    </li>
    <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>

你也可以在控制器中做同样的事情。


2
投票

你可以添加为。

var listClaims=new[] { new Claims(ClaimsType.SerialNumber,Id), new Claims(ClaimsType.Name,FullName), new Claims(ClaimsType.HomePhone,ContactNumber), new Claims(ClaimsType.Gender,Gender)};

var oAuthIdentity=new ClaimsIdentity(listClaims, otherparameter ...);

更多细节你可以查看System.Secutity.Claims.ClaimTypes。


1
投票

你可以这样做。

var fetchUser = context.UserMaster.Where(t => t.Email == model.Email).SingleOrDefault();
if (null == fetchUser)
    throw new Exception("Not found");
Session["User"] = fetchUser;
© www.soinside.com 2019 - 2024. All rights reserved.