MSSQLバックエンドでMVC3を使用してイントラネットアプリケーションを構築しています。認証とロール(カスタムロールプロバイダーを介して)が正しく機能しています。私が今やろうとしているのは、User.Identityをオーバーライドして、User.Identity.FirstNameのようなアイテムを許可することです。しかし、WindowsIdentityでこれを行う方法を示すコードが見つかりません
カスタムプロバイダーを書いてみました:
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をオーバーライドして、カスタムプリンシパルを設定します。
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になります。私は何が間違っているのですか?
編集:
上記のコードをglobal.asaxでコメントアウトしました。C#を使用してAuthorizeAttributeをオーバーライドしました:
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;
}
}
そして、私のプリンシパルを次のように調整しました:
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();
}
}
ブレークポイントを設定すると、時計はユーザーに次のように表示されます。
- ユーザー
- [CSupport.Model.CPrincipal]
- 身元
IDにアクセスできます。ただし、それでもWindowsIdentity CPrincipalは時計でのみアクセス可能であり、直接アクセスすることはできません。
編集: これに貢献してくれたすべての人に感謝します。さまざまな部品がどのように機能するかについての私の理解が大幅に広がりました。
両方の働き方ができたので、シェアしたいと思いました。
オプション1:Global.asaxの承認リクエストを上書きする
これは私が行っているものです。
Application_AuthenticateRequestを使用しなかったのは、(これによると、Windows認証がオンになっているにもかかわらずHttpContext.Current.Userがnullである)、ユーザーがWindows認証プロセスに入力されていないため、ユーザーを取得するために使用できるものがないためです。情報。
Application_AuthorizeRequestはチェーンの次のものであり、WindowsIDが取り込まれた後に発生します。
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);
}
}
これは、作成された新しいプリンシパルの更新された情報にアクセスする方法です。
[Authorize(Roles = "super admin")]
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
オプション2:AuthorizeAttributeをオーバーライドします
これはオーバーライドされたプリンシパルです(上記と同じです)
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);
}
}
これがAuthorize属性のオーバーライドです
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を変更し、新しい情報を利用します。
[CAuthorize(Roles = "super admin")] // <--
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
オプション1はすべてをグローバルに処理し、オプション2はすべてを個別のレベルで処理します。