如何在asp.net身份中进行会话管理

本文关键字:会话 管理 身份 asp net | 更新日期: 2023-09-27 18:15:20

我使用Asp.net身份用于登录,注册,忘记密码等,源代码取自以下链接:

http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset

http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity。

现在我有一个表,是UserMaster和注册期间,我要求以下字段: FullName, EmailId、密码ContactNumber、性别

My UserMaster包含以下字段:Id,FullName,EmailId,ContactNumber,Gender

现在,当用户将提交注册表单此FullName,EmailId,ContactNumber,性别将保存在UserMaster随着电子邮件,密码将保存在AspnetUser

我的注册方法与上面两个链接提供的相同。

在这里你可能会注意到,有没有关系我UserMaster和AspnetUser 所以在登录时,用户将进入他的电子邮件id登录我将使用这种方法await SignInManager.PasswordSignInAsync验证用户,如果这个方法返回成功那么我要做的是使用这个电子邮件id和检查这封邮件在我UserMaster,比赛将从UserMaster发现我将取回用户名并将其存储在会话和开拓我的应用程序在使用我的登录方法如下:

 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;
                            }

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

所以谁能告诉我如何做到这一点与aspnet身份??

如何在asp.net身份中进行会话管理

既然你使用的是Asp。Net Identity,您希望将会话相关的内容存储为声明。这很容易扩展为自定义声明。

作为题外话,我认为您最好简单地扩展ApplicationUser来保存额外的数据,如下所示。

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

步骤1 -定义一个或多个自定义索赔类型来保存您的附加信息

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";
}

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

步骤2—在登录过程中,为自定义索赔类型设置值

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访问身份信息。Net Identity 我们的自定义UserMaster

步骤3 -为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

第4步 -现在我们可以很容易地访问视图和/或控制器中的自定义索赔数据。假设您想使用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>

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

可以添加as:

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 . security . claims . claimtypes

你可以这样做:

var fetchUser = context.UserMaster.Where(t => t.Email == model.Email).SingleOrDefault();
if (null == fetchUser)
    throw new Exception("Not found");
Session["User"] = fetchUser;