これは、セキュリティ MVC4 RC と「Install-Package Microsoft.AspNet.WebApi」に関するものです。
カスタム Identity を作成します: System.Security.Principal.IIdentity で、認証 Cookie に貴重な文字列と int を格納します。
[Serializable]
public class SiteIdentity : IIdentity
{
public SiteIdentity(string name, string displayName, int userId, int siteId)
{
this.Name = name;
this.DisplayName = displayName;
this.UserId = userId;
this.SiteId = siteId;
}
public SiteIdentity(string name, UserInfo userInfo)
: this(name, userInfo.DisplayName, userInfo.UserId, userInfo.SiteId)
{
if (userInfo == null) throw new ArgumentNullException("userInfo");
this.AuthenticationType = userInfo.AutheticationType;
this.ClaimsIdentifier = userInfo.ClaimsIdentifier;
}
public SiteIdentity(FormsAuthenticationTicket ticket)
: this(ticket.Name, UserInfo.FromString(ticket.UserData))
{
if (ticket == null) throw new ArgumentNullException("ticket");
}
...完全ではありませんが、推測できると思います。
しかし、まず私の webapi コントローラーの構造。すべての webapi コントローラーを拡張する場所から、コントローラーを作成して拡張しました。
public class _AuthorizedApiController : ApiController
{
protected readonly Site.Web.Domain.Services.IUserServices _userServices;
public _AuthorizedApiController(Site.Web.Domain.Services.IUserServices userServices)
{
if (userServices == null) throw new ArgumentNullException("userServices");
this._userServices = userServices;
}
protected int CurrentUserId
{
get { return this.User.SiteIdentity().UserId; }
}
private Site.Web.Domain.Models.User currentUser;
public Site.Web.Domain.Models.User CurrentUser
{
get
{
return this.currentUser ??
(this.currentUser = this._userServices.GetUserFromIdentity(this.User.SiteIdentity()));
}
}
protected int CurrentSiteId
{
get { return this.User.SiteIdentity().SiteId; }
}
}
私のwebapiコントローラーは次のとおりです。
public class ServicioController : _AuthorizedApiController
{
//http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
//http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling
static readonly IServicioStatusRepository repositoryServicioStatus =
new ServicioStatusRepository(new Site.Web.Data.DatabaseFactory());
public ServicioController(Site.Web.Domain.Services.IUserServices userServices)
: base(userServices)
{
}
public IEnumerable<ServicioStatusA> GetServiciosStatus()
{
IEnumerable<ServicioStatusA> coleccion;
var estevalor = CurrentUser.SiteId;
}
ご覧のとおり、IoC を使用していますが、CurrentUser.SiteId を読み取ろうとすると問題が発生します。次のエラーが表示されます。
タイプ 'System.Web.Security.FormsIdentity' のオブジェクトをタイプ 'Site.Web.Models.SiteIdentity' にキャストできません。
この戻り関数では:
public static Site.Web.Models.SiteIdentity SiteIdentity(this System.Security.Principal.IPrincipal principal)
{
return (Site.Web.Models.SiteIdentity)principal.Identity;
}
この「アーティファクト」を global.asax.cs で使用して、セッションと情報を保持します。
public override void Init()
{
this.PostAuthenticateRequest += this.PostAuthenticateRequestHandler;
// this.EndRequest += this.EndRequestHandler;
base.Init();
}
private void PostAuthenticateRequestHandler(object sender, EventArgs e)
{
if (IsWebApiRequest())
{
string esto = "popopopopo";
}
HttpCookie authCookie = this.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (IsValidAuthCookie(authCookie))
{
// var formsAuthentication = ServiceLocator.Current.GetInstance<IFormsAuthentication>();
var formsAuthentication = new FormsAuthenticationService();
var ticket = formsAuthentication.Decrypt(authCookie.Value);
var siteIdentity = new SiteIdentity(ticket);
this.Context.User = new GenericPrincipal(siteIdentity, null);
// Reset cookie for a sliding expiration.
formsAuthentication.SetAuthCookie(this.Context, ticket);
}
}
そして、私が推測するのは、「通常の」MVC呼び出しがある場合はすべて正常に機能しますが、webapi呼び出しがある場合はCookieからすべてを回復できますが、次のとおりです。
System.Security.Principal.GenericPrincipal + ID: Site.Web.Model.SiteIdentity
それ以外の :
System.Security.Principal.GenericPrincipal + ID: System.web.security.FormsIdentity
どうぞよろしくお願いいたします。
ADEN-UM:
グーグル私はスレッドにもIDを保持しようとするので、PostAuthenticateRequestHandler内に次のように入力します:
System.Threading.Thread.CurrentPrincipal = this.Context.User;
しかし今、webapiだけでなく、すべてのリクエストで次のエラーが発生しました。
[SerializationException: Type is not resolved for member 'Site.Web.Models.SiteIdentity,Site.Web, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null'.]
Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0
Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress() +65
System.Web.HttpRequest.get_IsLocal() +23
System.Web.Configuration.CustomErrorsSection.CustomErrorsEnabled(HttpRequest request) +86
System.Web.HttpContextWrapper.get_IsCustomErrorEnabled() +45
System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext) +72
System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception) +115
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +105
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +45
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +61
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +49
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__4(IAsyncResult asyncResult) +28
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8970061
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184