当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - How to bypass System.Web.Http.AuthorizeAttribute.IsAuthorized

问题描述:

In our server, CORS is already enabled, so that scripts like ajax may communicate in our API. But this is only effective on API that has no SecureAttribute

This one is working properly:

[CorsPreflightEnabled]

public class DevicesController : ApiController

{

[CorsEnabled]

[HttpPost]

public bool Register(DTO::ClientInfo info)

While this one is always rejected:

[CorsPreflightEnabled]

[Http::Secure]

public class UserController : ApiController

{

[CorsEnabled]

[HttpPost]

public bool AddClaims(Domain::DTO.UserClaim claim)

This is the code for 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);

}

}

When I call the API using ajax the Method is set to OPTIONS and the value of calltoken is always null.

Now my question is, how can I bypass checking the security when the method is OPTIONS?

I found that, if I try to put values in calltoken via breakpoint, the IsAuthorized will be called again for the last time, and from there the Device header has now value.

I really hope that I explained myself well. If not, I may have to show some images.

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);

}

}

网友答案:

There is no way to bypass the authorisation attribute, that would be pretty insecure if it were possible. Your options are:

  1. Remove the attribute from the methods you need to call.
  2. Pass the correct security headers in the ajax call.
  3. Modify the SecureAttribute class to allow OPTIONS method (but that sounds pretty insecure too)
  4. Create new methods for ajax that don't have the attribute attached.

I'd suggest option 2.

分享给朋友:
您可能感兴趣的文章:
随机阅读: