在 MVC5 应用程序中使用会话的最佳方法

Tom*_*Tom 3 asp.net-mvc-5

我正在尝试在 asp.net mvc 5 应用程序中实现会话。该应用程序没有登录屏幕。应用程序检查访问该应用程序的用户是否存在于数据库中。Active Director 用户名在会话中被捕获并发送到存储过程以验证用户是否存在。如果存在,我需要在会话中存储用户配置文件信息。我创建了一个存储库类来访问数据。我从 global.asax 中的 session start 方法调用该方法。我想验证我的实现是否正确。如果信息发生更改,如何更新会话数据。

MCRHelper

 public static string GetShortname()
        {
            string username = HttpContext.Current.User.Identity.Name;
            return username.Split('\\')[1];
        }
Run Code Online (Sandbox Code Playgroud)

模型

[Serializable]
    public class UserProfileSessionData
    {
        public int UserProfileID { get; set; }
        public int EmployeeID { get; set; }
        public string Forename { get; set; }
        public string Surname { get; set; }
        public string PreferredName { get; set; }
        public string DefaultLanguageCode { get; set; }
        public string DefaultCountryCode { get; set; }
        public int TimeZoneID { get; set; }
        public string TimeZoneName { get; set; }
        public string Domain { get; set; }
        public string NetworkID { get; set; }
        public string EmailAddress { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

存储库类

public class SessionRespository
    {
        public List<UserProfileSessionData> GetUserProfileByNetworkId()
        {
            MCREntities db = new MCREntities();

            if (MCRHelper.UserValidate() == 1)
            {
                var userProfiles = db.spGetUserProfileByNetworkID(MCRHelper.GetShortname());
                return Mapper.Map<List<UserProfileSessionData>>(userProfiles);

            }
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

全球.asax

  protected void Session_Start(object sender, EventArgs e)
        {
            // set SessionUtil.User here
            SessionRespository sessionRespository = new SessionRespository();
            Session["UserProfile"] = sessionRespository.GetUserProfileByNetworkId();
        }
Run Code Online (Sandbox Code Playgroud)

Win*_*Win 6

我想验证一下我的实现是否正确。

首先,您不应该将登录用户的信息存储在会话状态中,更不用说如果可能的话,在 ASP.NET MVC 中不鼓励使用会话状态。

在 15 年前的 ASP.NET Membership Provider 出现之前,我们曾经将登录的用户信息存储在会话状态中。

由于您使用的是 ASP.NET MVC 5,因此您希望使用ASP.NET OWIN Cookie Middleware。实施比您想象的要容易得多。

Owin认证服务

private readonly HttpContextBase _context;
private const string AuthenticationType = "ApplicationCookie";

public OwinAuthenticationService(HttpContextBase context)
{
    _context = context;
}

public void SignIn(User user)
{
    IList<Claim> claims = new List<Claim>
    {
        new Claim(ClaimTypes.Sid, user.Id.ToString()),
        new Claim(ClaimTypes.Name, user.UserName),
        new Claim(ClaimTypes.GivenName, user.FirstName),
        new Claim(ClaimTypes.Surname, user.LastName),
    };

    ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);

    IOwinContext context = _context.Request.GetOwinContext();
    IAuthenticationManager authenticationManager = context.Authentication;

    authenticationManager.SignIn(identity);
}

public void SignOut()
{
    IOwinContext context = _context.Request.GetOwinContext();
    IAuthenticationManager authenticationManager = context.Authentication;

    authenticationManager.SignOut(AuthenticationType);
}
Run Code Online (Sandbox Code Playgroud)

启动.cs

您还需要配置启动以使所有这些发生。

[assembly: OwinStartup(typeof(YourApplication.Startup))]
namespace YourApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Account/Login")
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以开始在 Controller 和 Action 方法中使用[Authorize]属性。

[Authorize]
public class UsersController : Controller
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

这是我在 GitHub 上的示例应用程序,它使用 AD 进行身份验证。我有用户友好的登录屏幕,但如果您不想要的话,就不能使用它。

  • ***Http 是无状态的***,ASP.NET MVC 试图保持这种状态,因为在 ASP.NET Web 窗体中维护会话状态有很多问题。正如我所说,在会话状态中存储用户信息是 15 年前的方法,非常脆弱且难以维护,我们现在有更好的解决方案,例如 ***ASP.NET Identity*** 和 ***OWIN Middleware** *. 此外,如果您使用会话状态,则无法利用 ASP.NET MVC 在授权属性中的构建。如果您以后决定迁移到 ASP.NET Core,现在可以使用 OWIN 轻松实现。 (2认同)