如何绕过 System.Web.Http.AuthorizeAttribute.IsAuthorized
Posted
技术标签:
【中文标题】如何绕过 System.Web.Http.AuthorizeAttribute.IsAuthorized【英文标题】:How to bypass System.Web.Http.AuthorizeAttribute.IsAuthorized 【发布时间】: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);
【问题讨论】:
【参考方案1】:没有办法绕过授权属性,如果可能的话,那将是非常不安全的。您的选择是:
-
从您需要调用的方法中删除该属性。
在 ajax 调用中传递正确的安全标头。
修改 SecureAttribute 类以允许使用 OPTIONS 方法(但这听起来也很不安全)
为没有附加属性的 ajax 创建新方法。
我建议选项 2。
【讨论】:
是的,我在 ajax 中传递安全标头。问题是,它在第一次调用时无法检索,因为方法是OPTIONS
和 device
标头不包括在内。
那么也许您的第一个电话可能是获取安全标头?
嗯..好主意。但现在,我不知道该怎么做。如果我可以在CORS attribute
中获取标题值,我会尝试。
顺便说一句,你会怎么做数字 3?你能给我一些想法吗?
@fiberOptics 各种方式。您可以创建另一个构造函数,让您传入未检查的方法列表,然后在需要排除的函数上,传入这些方法。在属性代码中,在那里进行检查。以上是关于如何绕过 System.Web.Http.AuthorizeAttribute.IsAuthorized的主要内容,如果未能解决你的问题,请参考以下文章