Can I programmatically determine the database “context” to use based on user credentials?

北战南征 提交于 2019-12-11 21:18:51

问题


This is a followup to the question here, where the answer seems to refer to an overly-complicated and overly-specific (EF, which I'm not using - not even using an ORM).

There has to be a more straightforward way around this common scenario than the smoke, mirrors, and sorcery hinted at in that answer.

Note: I encased "context" in parenthesis because I'm not using EF, so it is not a literal "dbcontext" that I'm talking about here.

So I got to wondering: Could I set a global variable for each session when the user is authenticated and authorized?

e.g., when the user is authenticated/authorized, I would know which database context/contents should be served up to him.

So it seems I could set a value in Global.asax.cs' Application_Start() method and then either alter the RepositoriesInstaller (implementing IWindsorInstaller) class to conditionally register different concrete Repositories based on the user and what data he should have OR place conditional code in the concrete Repository itself to use this or that database instance.

Is this feasible? Is one way (altering the RepositoriesInstaller / altering the concrete Repositories class) preferred?


回答1:


Have a look at this answer which will show you how to resolve the correct repository based on a key or value.

If you want to store it with the authorized user, you need to simple serialize the data and store it on the authenticated cookie:

Create a Model to represent the logged in information:

public class AuthenticatedMember
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public int SiteNumber { get; set; }
}

Do something like a login in your controller:

var authenticatedMember = MembershipManager.ValidateLogin(model.Email, model.Password);

var cookie = FormsAuthentication.GetAuthCookie(authenticatedMember.Id.ToString(), false);
var ticket = FormsAuthentication.Decrypt(cookie.Value);

var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, authenticatedMember.ToJson(), ticket.CookiePath);

cookie.Value = FormsAuthentication.Encrypt(newTicket);
Response.Cookies.Add(cookie);

Then use a model binder to deserialize the AuthenticatedMember when you require:

public class AuthenticatedMemberModelBinder : IModelBinder
{
    #region IModelBinder Members

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.Model != null)
        {
            throw new InvalidOperationException("Cannot update instances");
        }

        if (controllerContext.RequestContext.HttpContext.Request.IsAuthenticated)
        {
            var cookie = controllerContext
                .RequestContext
                .HttpContext
                .Request
                .Cookies[FormsAuthentication.FormsCookieName];

            if (null == cookie)
                return null;

            var decrypted = FormsAuthentication.Decrypt(cookie.Value);

            if (!string.IsNullOrEmpty(decrypted.UserData))
            {
                return JsonConvert.DeserializeObject<AuthenticatedMember>(decrypted.UserData);
            }
        }
        return null;
    }

    #endregion
}


来源:https://stackoverflow.com/questions/21388655/can-i-programmatically-determine-the-database-context-to-use-based-on-user-cre

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!