スコープと WIF に関してかなり複雑な問題が発生しています。すべてのアプリケーション セキュリティを処理するサービス クラス (SecurityService) があります。クレームの作成、ClaimsPrincipal の設定などを行います。Ninject とバインドされています。
現在、WIF には ClaimsAuthorizationManager クラスと ClaimsAuthenticationManager クラスがあり、必要に応じてキャッシュされたプリンシパルを使用する方法があります。これら 2 つのクラスはそれぞれ SecurityService を使用し、プリンシパルはそのクラスで作成および格納されます。
プリンシパルがキャッシュされると、SecurityService がそのキャッシュされたバージョンを受け取り、それをインスタンス変数として使用できるように、コードをセットアップしました。サービスは InRequestScope() にバインドされています。WIF クラスにはパラメーターのないコンストラクターが必要なので、Ninject DependencyResolver.Current.GetService<>() メソッドを使用します。
問題は、2 番目のコピーを作成しているように見えるか、WIF 作業が発生しているときに RequestScope が開始されていないことです。SecurityService は、コード内のオブジェクトに割り当てられたときに、クレームが割り当てられたプリンシパルを持っていません。
認証マネージャーの例を次に示します。
public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager
{
private readonly SecurityService _MySecurityService;
public HeritageClaimsAuthenticationManager(SecurityService heritageSecurityService)
{
_MySecurityService = heritageSecurityService;
}
public MyClaimsAuthenticationManager()
: this(System.Web.Mvc.DependencyResolver.Current.GetService(typeof(SecurityService)) as SecurityService)
{
}
/// <summary>
/// Provides the framework extension to transform an incoming principal into an application specific principal.
/// </summary>
/// <param name="resourceName"></param>
/// <param name="incomingPrincipal"></param>
/// <returns>An Application specific ClaimsPrincipal</returns>
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated)
{
return TransformPrincipal(incomingPrincipal);
}
//Something is wrong with the incoming principal. Let the base implementation handle it.
return base.Authenticate(resourceName, incomingPrincipal);
}
/// <summary>
/// Given an existing claims principal, transform it to fit the needs of the current application,
/// then store it in session.
/// </summary>
/// <param name="incomingPrincipal"></param>
/// <returns></returns>
public ClaimsPrincipal TransformPrincipal(ClaimsPrincipal incomingPrincipal)
{
_MySecurityService.CreateHeritagePrincipal(incomingPrincipal);
...
return _MySecurityService.Principal;
}
}
WIF のコンストラクター要件により、DependencyResolver を使用します。この時点で、_MySecurityService.Principal
価値があります。ただし、リクエスト ライフ サイクルの後半で、Ninject はプリンシパルを持たないサービスを返します。
また、IHttpModule を使用して WindowsPrincipal をインターセプトし、認証マネージャーを使用してhttp://leastprivilege.com/2012/04/04/identity-in-net-4-5part-2-claims-transformation-inに従ってクレームを変換します-asp-net-beta-1/ .
それもうまく機能しているようです。バインディングを InRequestScope() から InSingletonScope() に変更すると、すべてがうまく機能します。もちろん、これは複数のユーザーでは機能しません。また、HttpContext.User を見ると、ClaimsPrincipal が含まれています。
バインディングは次のとおりです。
Bind<ISecurityService>()
.ToMethod<MySecurityService>(
m => new MySecurityService(
new Collection<ISecurityClaimProvider>()
{
new UserClaimDao(new MyDbContext("MyDbContext"))
}
)).InRequestScope();
DAO がサービスのアプリケーション クレームを戻す場所。_MySecurityService.CreateHeritagePrincipal(incomingPrincipal)
要約すると、すべてが正しく配線されているようです。WIF クラスの Ninject 操作は、リクエストの範囲外で行われているようです。
何か不足していますか?範囲については正しいですか?もしそうなら、それを回避する方法はありますか?そうでない場合、このシナリオにどのように対処していますか?
実際、WIF クラスが動作する前に Application_BeginRequest が発生することを確認したので、完全に途方に暮れています。