MVC3 Windows身份验证覆盖User.Identity [英] MVC3 Windows Authentication override User.Identity

查看:615
本文介绍了MVC3 Windows身份验证覆盖User.Identity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立一个内部网使用MVC3与MSSQL后端应用程序。我有身份验证和角色(通过自定义角色提供者)工作正常。什么我想现在要做的是压倒一切的User.Identity允许像User.Identity.FirstName项目。但是,我找不到任何code,它会告诉我如何的WindowsIdentity做到这一点。

I am building a intranet application using MVC3 with a MSSQL backend. I have authentication and roles (through a custom roles provider) working properly. What I am trying to do now is overriding User.Identity to allow for items like User.Identity.FirstName. But I cannot find any code that will show me how do this in WindowsIdentity

我曾尝试编写自定义提供:

I have tried writing a custom provider:

public class CPrincipal : WindowsPrincipal
{
    UserDAL userDAL = new UserDAL();
    public CPrincipal(WindowsIdentity identity)
        : base(identity)
    {
        userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
        this.identity = identity;
    }
    public UserInfo userInfo { get; private set; }
    public WindowsIdentity identity { get; private set; }
}

和覆盖WindowsAuthentication来填充自定义主体。

and overriding the WindowsAuthentication to populate the custom principal.

    void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
    {
        if (e.Identity != null && e.Identity.IsAuthenticated)
        {
            CPrincipal cPrincipal = new CPrincipal(e.Identity);
            HttpContext.Current.User = cPrincipal;
        }
    }

我在认证功能断点,并正在填充校长;然而,当我把一个断点在控制器中,用户仅仅是其正常RolePrincipal,而不是我的自定义主体。我在做什么错了?

I have a breakpoint in the authentication function and the principal is being populated; however, when I put a breakpoint in the controllers, the User is just its normal RolePrincipal, instead of my custom principal. What am I doing wrong?

编辑:

我注释掉code以上在Global.asax。
 我已经覆盖了AuthorizeAttribute使用C#:

I commented out the code above in the global.asax. I have overridden the AuthorizeAttribute using C#:

public class CAuthorize : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }


        IIdentity user = httpContext.User.Identity;
        CPrincipal cPrincipal = new CPrincipal(user);
        httpContext.User = cPrincipal;

        return true;
    } 

}

和调整,我主要为以下内容:

And adjusted my principal to the following:

public class CPrincipal : IPrincipal
{
    private UserDAL userDAL = new UserDAL();
    public CPrincipal(IIdentity identity)
    {
        userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
        this.Identity = identity;
    }
    public UserInfo userInfo { get; private set; }

    public IIdentity Identity { get; private set; }

    public bool IsInRole(string role)
    {
        throw new NotImplementedException();
    }
}

现在我当我把一个断点,手表显示以下用户:

Now I when I put a breakpoint in, the watch shows the following in user:


  • 用户

    • [CSupport.Model.CPrincipal]

    • 身份

    身份是accessable;然而,它仍然是的WindowsIdentity
    CPrincipal直接只手表访问,不能访问。

    Identity is accessable; however, it is still the WindowsIdentity CPrincipal is only accessible in the watch and not accessible directly.

    编辑:
    感谢大家谁了这种情况。你已经极大地扩展了我的各个部分是如何运作的了解。

    Thanks to everyone who contributed to this. You have greatly expanded my understanding of how the various parts work.

    我有两种方式工作,所以我想我会分享。

    I got both ways to work, so I thought I would share.

    选项1:覆盖的授权请求在Global.asax中

    Option 1: Override the Authorize Request in Global.asax

    这是一个我一起去。

    我没有,因为(根据该使用Application_AuthenticateRequest:<一href=\"http://stackoverflow.com/questions/1663535/httpcontext-current-user-is-null-even-though-windows-authentication-is-on\">HttpContext.Current.User为null即使Windows身份验证是)用户没有在Windows身份验证过程被填充,因此没有什么,我可以使用去获得用户信息。

    I did not use Application_AuthenticateRequest because (according to this: HttpContext.Current.User is null even though Windows Authentication is on) the user has not been populated in a Windows authentication process and thus there is nothing that I can use to go get the user information.

    Application_AuthorizeRequest是链中的下一个和Windows身份在带来了后会发生。

    Application_AuthorizeRequest is the next in the chain and happens after the windows identity is brought in.

        protected void Application_AuthorizeRequest(object sender, EventArgs e)
        {
            if (User.Identity.IsAuthenticated && Roles.Enabled)
            {
                Context.User = new FBPrincipal(HttpContext.Current.User.Identity);
            }
        }
    

    这是主要的控

    public class CPrincipal : IPrincipal
    {
        private UserDAL userDAL = new UserDAL();
        public CPrincipal(IIdentity identity)
        {
            userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
            this.Identity = identity;
        }
        public UserInfo userInfo { get; private set; }
    
        public IIdentity Identity { get; private set; }
    
        public bool IsInRole(string role)
        {
            return userDAL.IsUserInRole(userInfo.UserName, role);
        }
    }
    

    这是你如何访问所创建的新的主要更新的信息。

    This is how you access the updated info in the new Principal that was created.

        [Authorize(Roles = "super admin")]
        public ActionResult Dashboard()
        {
            string firstname = (User as CPrincipal).userInfo.FirstName; // <--
            DashboardModel dModel = reportDAL.GetChartData();
            return View(dModel);
        }
    

    选项2:重写AuthorizeAttribute

    Option 2: Override the AuthorizeAttribute

    这是重写的校长(这是与上面相同)

    This is the overridden Principal (It is the same as above)

    public class CPrincipal : IPrincipal
    {
        private UserDAL userDAL = new UserDAL();
        public CPrincipal(IIdentity identity)
        {
            userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
            this.Identity = identity;
        }
        public UserInfo userInfo { get; private set; }
    
        public IIdentity Identity { get; private set; }
    
        public bool IsInRole(string role)
        {
            return userDAL.IsUserInRole(userInfo.UserName, role);
        }
    }
    

    下面是授权属性的超控

    public class CAuthorize : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool authorized = base.AuthorizeCore(httpContext);
            if (!authorized)
            {
                return false;
            }
    
    
            IIdentity user = httpContext.User.Identity;
            CPrincipal cPrincipal = new CPrincipal(user);
            httpContext.User = cPrincipal;
    
            return true;
        } 
    
    }
    

    这是你改变AuthorizeAttribute使用和利用新的信息,这

    This is where you change which AuthorizeAttribute to use and utilizing the new information.

        [CAuthorize(Roles = "super admin")] // <--
        public ActionResult Dashboard()
        {
            string firstname = (User as CPrincipal).userInfo.FirstName; // <--
            DashboardModel dModel = reportDAL.GetChartData();
            return View(dModel);
        }
    

    选项1处理全部的寄托全球范围内,选择2在个人层面处理一切。

    Option 1 handles everthing globally, option 2 handles everything at an individual level.

    推荐答案

    相反,做这种方式,你应该覆盖Global.asax中Application_AuthenticateRequest方法,然后用Current.User而不是HttpContext.Current.User(不知道为什么,但是有区别的)。

    Instead of doing it this way, you should override the Application_AuthenticateRequest method in global.asax, then use Current.User rather than HttpContext.Current.User (not sure why, but there is a difference).

    然后,一个简单的方法来访问这个在您的控制器是创建一个扩展方法?事情是这样的:

    Then, an easy way to access this in your controller is to create an extension method? Something like this:

    public static class IIdentityExtensions {
        public static IMyIdentity MyIdentity(this IIdentity identity) {
            return (IMyIdentity)identity;
        }
    }
    

    那么你可以说 User.Identity.IMyIdenty()。名字。你也许可以做到这一点作为一个属性为好。

    then you can just say User.Identity.IMyIdenty().FirstName. You could probably do this as a property as well.

    下面是code我使用:

    Here is the code I use:

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication
           .Decrypt(authCookie.Value);
        var identity = new MyIdentity(authTicket.Name, "Forms", 
           FormsAuthenticationHelper.RetrieveAuthUserData(authTicket.UserData));
        Context.User = new GenericPrincipal(identity, 
           DependencyResolver.Current.GetService<ISecurityHandler>()
              .GetRoles(identity.Name).ToArray());
    }
    

    现在,忽视了DependencyResolver东西,定制身份验证票证的东西,这是pretty基本和正常工作对我来说。

    Now, ignoring the DependencyResolver stuff and the custom auth ticket stuff, this is pretty basic and works correctly for me.

    然后,在我的应用程序,当我需要的信息从我的定制身份,我只是用投它((IMyIdentity)User.Identity).FirstName 或什么我需要。这不是火箭科学,它的工作原理。

    Then, in my app, when i'm need info from my custom identity, i just cast it with ((IMyIdentity)User.Identity).FirstName or whatever I need. It's not rocket science, and it works.

    这篇关于MVC3 Windows身份验证覆盖User.Identity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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