MVC3 Windows身份验证覆盖User.Identity [英] MVC3 Windows Authentication override 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屋!