あなたは、(1)ユーザー情報を取得するのに最適な場所と、(2)セッションに保存する方法の2つの質問をしました。私は答えるだろう(1)そしてそうすることで、おそらくセッションに追加情報を入れる必要はないことを示しているだろう。
あなたのアプリケーションではWindows認証が使用されていると言われています。これは、アプリケーションが要求を受け取る前にIIS/HttpListenerによってユーザーが認証されていることを意味します。リクエストを受け取ったらWindowsPrincipal
がHttpContext.User
になります。これにより、ウィンドウズのユーザー名と広告の役割はすでに確立されていますが、データベースに格納されている追加の役割を使用したいと考えています...
IAuthorizationFilter
と一緒に仕事をしてください。この方法に従うことで、データベースからフェッチする追加の役割やその他の情報がコントローラメソッドで利用できます。さらに重要なことは、ユーザーの資格情報を確認する必要がある追加のライブラリコードです。
.Net 4.5より前のバージョンでは、WindowsPrincipal
に追加情報を追加する場合は、システム提供のユーザーをIPrincipal
インターフェイスを実装した別のオブジェクトに置き換えてください。このアプローチはまだ利用可能です(と私は何をお勧めします).Net 4でWindows Identity Foundation(WIF)の導入以来。図5のWindowsPrincipal
は、 System.Security.Claims.ClaimsIdentityClaimsIdentity
から派生したもので、システム提供のプリンシパルに追加の役割(およびその他の有用な情報)を追加することができます。しかし、いくつかの人々が発見したように、Windowsにバグ/機能があり、プログラムで追加されたロールをチェックするときに例外The trust relationship between the primary domain and the trusted domain failed
がスローされる可能性があります。私たちは、これを避ける簡単で信頼性の高い方法は、ユーザーをGenericPrincipal
に置き換えることであることが判明しました。必要
ステップ:
(1)IAuthorizationFilter
を作成します。
class MyAuthorizationFilter : IAuthorizationFilter
{
AuthService _authService;
public MyAuthorizationFilter(AuthService authService)
{
_authService = authService;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
var principal = filterContext.HttpContext.User;
if (principal.Identity != null && principal.Identity.IsAuthenticated)
{
// Add username (and other details) to session if you have a need
filterContext.HttpContext.Session["User"] = principal.Identity.Name;
// get user info from DB and embue the identity with additional attributes
var user = _authService.GetUserInfo(principal.Identity.Name);
// Create a new Principal and add the roles belonging to the user
GenericPrincipal gp = new GenericPrincipal(principal.Identity, user.RoleNames.ToArray());
filterContext.HttpContext.User = gp;
}
}
}
(2)フィルタを登録します。これはコントローラレベルで、またはグローバルに登録することができます。通常は、App_Start\FilterConfig.cs
でこれを行います。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyAuthorizationFilter(new AuthService()));
}
}
(3)ユーザ識別およびその他の資格情報についての質問に答えるために、アプリケーションコードで提供GenericPrincipal
を使用してください。例えばあなたのコントローラのメソッドでは、あなたのフィルタによってGenericPrincipal
に保存されているユーザー名やその他の "申し立て"(例:電子メールアドレス)にアクセスできます。
public ActionResult Index()
{
ViewBag.Name = HttpContext.User.Identity.Name;
if(HttpContext.User.IsInRole("Administrator"))
{
// some role-specific action
}
return View();
}
あなたが主な役割を記録する組み込みのメカニズムを使用しましたので、あなたはどこにでもHttpContext.User
かSystem.Threading.Thread.CurrentPrincipal
を使用してからユーザーの詳細にアクセスすることができます。コントローラのメソッドでAuthorizeAttribute
を使用して、特定のロールまたはユーザーが使用できるアクションを宣言することもできます。例えば
public class HomeController : Controller
{
[Authorize(Roles = "Administrator")]
public ActionResult Admin()
{
return View();
}
私は、これは
-Rob
出典
2016-09-24 21:12:51
Rob
Robありがとうございました。あなたの役割を果たすあなたのソリューションは素晴らしいですが、私はうんざりして、ユーザーIDなどのデータベースからいくつかの情報を取得するような理由でセッションを行うためにユーザーIDを取得する必要があります。 :-)私はこれを行うための最良の場所がどこか分かりません。ありがとう。 – Jenan
こんにちはジェナン。 AuthorizationFilterのセッションにユーザー名を追加する必要がある場合(これを表示するために回答を更新しました)、追加することができますが、なぜこれを行う必要があるのか分かりません。 HttpConext.User(コントローラ内)を使用して任意のコードからプリンシパル(およびそこからIdentity.Username)にアクセスすることができます。また、ライブラリコードを深く理解していれば、System.Threading.Thread.CurrentPrincipalを使用できます。 – Rob
ロブ、ありがとうございました。この答えは私にとっては素晴らしいことです。 – Jenan