Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WebApi从HttpActionContext序列化对象_C#_Javascript_Serialization_Asp.net Web Api_Authorization - Fatal编程技术网

C# WebApi从HttpActionContext序列化对象

C# WebApi从HttpActionContext序列化对象,c#,javascript,serialization,asp.net-web-api,authorization,C#,Javascript,Serialization,Asp.net Web Api,Authorization,编辑:我改变了我的方法。现在我正在使用MessageHandler。多亏了拉西尔,他指明了挖掘的方向 以下链接对我非常有用: 我有一个WebApi项目,需要为其提供自定义授权。特殊的令牌对象被添加到来自前端的每个请求中。诸如此类: SendApiRequest: function (controller, action, data, successCallback, failureCallback) { var url = ROUTER.GetApiUrl(controller, a

编辑:我改变了我的方法。现在我正在使用MessageHandler。多亏了拉西尔,他指明了挖掘的方向

以下链接对我非常有用:


我有一个WebApi项目,需要为其提供自定义授权。特殊的令牌对象被添加到来自前端的每个请求中。诸如此类:

SendApiRequest: function (controller, action, data, successCallback, failureCallback) {
    var url = ROUTER.GetApiUrl(controller, action);

    data.Token = TOKEN;

    jQuery.ajax({
        type: 'POST',
        dataType: 'json',
        url: url,
        data: data,
        success: function (result) {
            if (typeof successCallback == 'function') {
                successCallback(result);
            }
        },
        error: function (result) {
            if (typeof failureCallback == 'function') {
                failureCallback(result);
            }
        }
    });}
public class UserToken
{
    public Int64 TokenID;
    public int UserID;
    public string TokenValue;
    public string IP;
    public string Hash;

    public DateTime CreatedOn;
    public DateTime ActionOn;
}
我有一个AuthorizationAttribute,我需要从请求中序列化令牌对象。但是找不到任何自动的方法来做到这一点

public class CustomAuthorizationAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(HttpActionContext context)
    {
        UserToken token = null;

        //HOW TO SERIALIZE token object from context?

    }
}
UserToken类如下所示:

SendApiRequest: function (controller, action, data, successCallback, failureCallback) {
    var url = ROUTER.GetApiUrl(controller, action);

    data.Token = TOKEN;

    jQuery.ajax({
        type: 'POST',
        dataType: 'json',
        url: url,
        data: data,
        success: function (result) {
            if (typeof successCallback == 'function') {
                successCallback(result);
            }
        },
        error: function (result) {
            if (typeof failureCallback == 'function') {
                failureCallback(result);
            }
        }
    });}
public class UserToken
{
    public Int64 TokenID;
    public int UserID;
    public string TokenValue;
    public string IP;
    public string Hash;

    public DateTime CreatedOn;
    public DateTime ActionOn;
}
所以问题是:如何从HttpActionContext序列化自定义对象


谢谢。

这就是我在处理与你类似的案件时所做的

您不需要创建自己的Authorize属性,而是可以创建一个MessageHandler,用于检查令牌并在每次请求时对其进行验证。此消息处理程序负责在当前线程中填充主体,因此Authorize属性可以按预期工作,允许授权客户端访问相关控制器/操作

以下是我的授权消息处理程序的外观:

public class AuthMessageHandler : DelegatingHandler
{
    protected ITokenProvider TokenProvider { get; private set; }
    protected IPrincipalProvider PrincipalProvider { get; private set; }

    public AuthMessageHandler(ITokenProvider tokenProvider, IPrincipalProvider principalProvider)
    {
        TokenProvider = tokenProvider;
        PrincipalProvider = principalProvider;
    }


    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Identity identity = null;
        string token = ExtractToken(request);

        if (token != null && TokenProvider.Verify(token, out identity))
        {
            request.Properties.Add(Constants.IdentityKey, identity);
            var principal = PrincipalProvider.CreatePrincipal(identity);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
        }

        return base.SendAsync(request, cancellationToken);
    }


    private string ExtractToken(HttpRequestMessage request)
    {
        IEnumerable<string> tokenValues = null;
        if (request.Headers.TryGetValues(Constants.TokenHeaderKey, out tokenValues))
            return tokenValues.First();

        return null;
    }
}
公共类AuthMessageHandler:DelegatingHandler { 受保护的ITokenProvider令牌提供程序{get;private set;} 受保护的IPrincipProvider PrincipalProvider{get;private set;} 公共AuthMessageHandler(ITokenProvider令牌提供程序、IPrincipalProvider principalProvider) { 令牌提供者=令牌提供者; PrincipalProvider=PrincipalProvider; } 受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken) { Identity=null; 字符串令牌=提取令牌(请求); if(token!=null&&TokenProvider.Verify(token,out-identity)) { request.Properties.Add(Constants.IdentityKey,identity); var principal=PrincipalProvider.CreatePrincipal(标识); Thread.CurrentPrincipal=主体; HttpContext.Current.User=主体; } 返回base.sendaync(请求、取消令牌); } 私有字符串提取令牌(HttpRequestMessage请求) { IEnumerable tokenValues=null; if(request.Headers.TryGetValues(Constants.TokenHeaderKey,out-tokenValues)) 返回tokenValues.First(); 返回null; } } 请注意:

  • TokenProvider和PrincipalProvider都在这里注入。第一个负责验证令牌,如果有效,则返回标识数据,以便在整个请求中都可用
  • IPrincipal提供程序只创建一个GenericPrincipal,然后将其分配给Thread.CurrentPrincipal和上下文用户(HttpContext.Current.user)。这确保了Authorize属性在以后检查当前主体中是否已进行身份验证时起作用
  • 在本例中,我将在头中传递令牌信息,我更喜欢这样。(您可能还需要授权GET请求)
  • 如果需要将数据从消息处理程序传递到控制器,可以使用request.Properties,这就是我将标识信息与request.Properties.Add(Constants.IdentityKey,Identity)放在一起的原因;因此,控制器可以使用它。有几种方法可以实现这一点,但是对于这种类型的数据,这本字典几乎是一种便宜的传输工具

  • 如果你有任何问题,请告诉我。这实际上比看起来更简单。

    谢谢。这正是我想要的。这是一篇很好的文章,可以帮助您开始理解Http消息处理程序。如果您想重定向到另一个url而不是发送403,您将如何处理它?我还没有这样做,但您可以使用以下指针: