【发布时间】:2014-07-08 09:13:17
【问题描述】:
在我们的服务器中,CORS 已经启用,因此像 ajax 这样的脚本可以在我们的 API 中进行通信。但是这只对没有SecureAttribute的API有效
这个工作正常:
[CorsPreflightEnabled]
public class DevicesController : ApiController
{
[CorsEnabled]
[HttpPost]
public bool Register(DTO::ClientInfo info)
虽然这个总是被拒绝:
[CorsPreflightEnabled]
[Http::Secure]
public class UserController : ApiController
{
[CorsEnabled]
[HttpPost]
public bool AddClaims(Domain::DTO.UserClaim claim)
这是 SecureAttribute 的代码:
public class SecureAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var calltoken = HttpContext.Current.Request.Headers["Device"] ?? "";
var token = JsonConvert.DeserializeObject<DeviceCallToken>(calltoken) ?? new DeviceCallToken();
var cachetoken = new ClientAuthentication().VerifyDevice(token);
if (cachetoken != null)
{
// if a cachetoken was successfully extracted from our records,
// then store the information into the principal for possible reuse
var principal = AppPrincipal.Current;
var identity = principal.Identity as AppIdentity;
identity.ServiceHeader.SessionId = token.SessionId;
identity.ServiceHeader.ClientKey = cachetoken.ClientKey;
identity.ServiceHeader.DeviceCode = cachetoken.DeviceCode;
identity.ServiceHeader.Merchant = cachetoken.Merchant;
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
return cachetoken != null && !string.IsNullOrWhiteSpace(cachetoken.Salt);
}
}
当我使用ajax 调用API 时,Method 设置为OPTIONS,calltoken 的值始终为null。
现在我的问题是,当方法为OPTIONS 时,如何绕过检查安全性?
我发现,如果我尝试通过断点将值放入calltoken,最后一次将再次调用IsAuthorized,并且从那里Device 标头现在具有值。
我真的希望我能很好地解释自己。如果没有,我可能需要展示一些图像。
编辑:工作代码
public class SecureAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var calltoken = HttpContext.Current.Request.Headers["Device"] ?? "";
var token = JsonConvert.DeserializeObject<DeviceCallToken>(calltoken) ?? new DeviceCallToken();
var cachetoken = new ClientAuthentication().VerifyDevice(token);
if (cachetoken != null)
{
// if a cachetoken was successfully extracted from our records,
// then store the information into the principal for possible reuse
var principal = AppPrincipal.Current;
var identity = principal.Identity as AppIdentity;
identity.ServiceHeader.SessionId = token.SessionId;
identity.ServiceHeader.ClientKey = cachetoken.ClientKey;
identity.ServiceHeader.DeviceCode = cachetoken.DeviceCode;
identity.ServiceHeader.Merchant = cachetoken.Merchant;
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
else
{
var originalRequest = actionContext.Request;
var isCorsRequest = originalRequest.Headers.Contains("Origin");
if (originalRequest.Method == HttpMethod.Options && isCorsRequest)
{
// Allow to penetrate
return true;
}
}
return cachetoken != null && !string.IsNullOrWhiteSpace(cachetoken.Salt);
}
}
【问题讨论】:
标签: c# ajax asp.net-mvc cors