我从System.Web.Http.AuthorizeAttribute继承创建一个自定义的授权/认证程序,以满足使用ASP.NET MVC 4开发这增加了安全性,使用适合于Ajax的网络API从Web调用Web应用程序的一些不寻常的要求客户。 要求是:
- 用户必须在每次进行交易,以验证别人还没有走到有人登录并走开后工作站一次登录。
- 角色不能分配到节目时间的Web服务方法。 他们必须在运行时分配,所以管理员可以配置此。 此信息存储在系统数据库中。
Web客户端是一个单页的应用程序(SPA),所以典型的窗体身份验证不工作这么好,但我想重用尽可能多的ASP.NET安全框架,因为我能满足要求。 定制AuthorizeAttribute上确定哪些角色与Web服务方法相关的伟大工程的要求2。 我接受三个参数,应用程序名称,资源名称和运作,以确定哪些角色与方法有关。
public class DoThisController : ApiController
{
[Authorize(Application = "MyApp", Resource = "DoThis", Operation = "read")]
public string GetData()
{
return "We did this.";
}
}
我重写OnAuthorization方法来获得角色和验证用户。 由于用户被认证为每个事务我减少通过在同一步骤中进行认证和授权的来回颤。 我通过使用通过在HTTP头中的加密证书基本身份验证您可以通过Web客户端的用户凭据。 所以我OnAuthorization方法是这样的:
public override void OnAuthorization(HttpActionContext actionContext)
{
string username;
string password;
if (GetUserNameAndPassword(actionContext, out username, out password))
{
if (Membership.ValidateUser(username, password))
{
FormsAuthentication.SetAuthCookie(username, false);
base.Roles = GetResourceOperationRoles();
}
else
{
FormsAuthentication.SignOut();
base.Roles = "";
}
}
else
{
FormsAuthentication.SignOut();
base.Roles = "";
}
base.OnAuthorization(actionContext);
}
GetUserNameAndPassword检索来自HTTP标题的凭据。 然后我用Membership.ValidateUser验证凭据。 我有一个自定义成员资格提供程序和角色提供插在打了一个自定义数据库。 如果用户进行身份验证我然后检索的资源和操作的角色。 从那里,我用的是基地OnAuthorization完成授权过程。 这里是它打破了。
如果用户通过验证我用的是标准的形式验证方法进行登录(FormsAuthentication.SetAuthCookie)的用户,如果他们失败,我将他们注销(FormsAuthentication.SignOut)。 但问题似乎是基地OnAuthorization类没有获得校长让IsAuthenticated设置为正确的值被更新。 它始终是一个落后一步。 我的猜测是,它使用的是没有更新,直到有一个往返于web客户端缓存的一些价值。
因此,所有这些导致了我的具体问题是,是否有另一种方式来IsAuthenticated设置为当前主要的正确值,而无需使用cookies吗? 在我看来,这饼干真的不适用于这种特定情况下,我每次都进行身份验证。 我知道IsAuthenticated原因未设置为正确的值我也重写HandleUnauthorizedRequest方法如下:
protected override void HandleUnauthorizedRequest(HttpActionContext filterContext)
{
if (((System.Web.HttpContext.Current.User).Identity).IsAuthenticated)
{
filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
这让我回的禁web客户端,如果故障是由于授权,而不是认证的,它可以做出相应的响应状态代码。
那么,什么是设置IsAuthenticated在这种情况下当前原理的正确方法?