这是关于安全性MVC4 RC和“Install-Package Microsoft.AspNet.WebApi”。
我创建了一个自定义身份:System.Security.Principal.IIdentity,其中我将一些有价值的字符串和int存储在身份验证cookie中:
[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 + Identity:Site.Web.Model.SiteIdentity
而不是:
System.Security.Principal.GenericPrincipal + Identity:System.web.security.FormsIdentity
提前感谢您的支持
ADEN-UM:
谷歌搜索我也尝试将身份保留在线程中,所以在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