如何绕过System.Web.Http.AuthorizeAttribute.IsAuthorized
本文关键字:AuthorizeAttribute IsAuthorized Http Web 何绕过 System | 更新日期: 2023-09-27 18:04:06
在我们的服务器中,CORS已经启用,因此像ajax
这样的脚本可以在我们的API中通信。但这只对没有SecureAttribute
这个工作正常:
[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
头现在具有值。
我真的希望我解释清楚了。如果没有,我可能要展示一些图片。
EDIT: Working code
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);
}
}
没有办法绕过授权属性,如果可能的话,那将是非常不安全的。你的选择是:
- 从需要调用的方法中删除属性。
- 在ajax调用中传递正确的安全头。
- 修改SecureAttribute类以允许OPTIONS方法(但这听起来也很不安全)
- 为ajax创建没有附加属性的新方法。
我建议选择2