c# - WebApi 从 HttpActionContext 序列化对象

标签 c# javascript serialization asp.net-web-api authorization

编辑:我改变了我的方法。现在我正在使用消息处理程序。感谢 Raciel,他指出了挖掘的方向。

这些链接对我来说非常有用: MessageHandlers overview Using own Principal classes

<小时/>

我有一个WebApi项目,需要为其提供自定义授权。特殊的 Token 对象被添加到前端的每个请求中。类似这样的事情:

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

我有一个 AuthorizationAttribute,我需要以某种方式从请求中序列化 Token 对象。但找不到任何自动方法来做到这一点。

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

        //HOW TO SERIALIZE token object from context?

    }
}

UserToken 类看起来像这样:

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 序列化自定义对象?

谢谢。

最佳答案

这就是我在处理与您类似的案例时所做的。

您可以创建一个 MessageHandler 来检查 token 并在每个请求时验证它,而不是创建自己的 Authorize 属性。此消息处理程序负责填充当前线程中的 Principal,因此 Authorize 属性可以按预期工作,允许授权客户端访问相关 Controller /操作。

这就是我的授权消息处理程序的样子:

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

请注意:

  1. TokenProvider和PrincipalProvider都在这里注入(inject)。第一个负责验证 token ,如果有效,则返回身份数据,以便在请求中可用。
  2. IPrincipal 提供程序只是创建一个 GenericPrincipal,然后将其分配给 Thread.CurrentPrincipal 和上下文用户 (HttpContext.Current.User)。这可以确保 Authorize 属性稍后在检查当前主体中的 IsAuthenticated 时起作用。
  3. 在本例中,我在 header 中传递 token 信息,这是我更喜欢的。 (您可能还需要授权 GET 请求)
  4. 如果您需要将数据从消息处理程序传递到 Controller ,则可以使用 request.Properties,这就是为什么我使用 request.Properties.Add(Constants.IdentityKey, Identity); 将身份信息放在那里的原因。所以它可供 Controller 使用。有多种方法可以实现此目的,但对于此类数据来说,此字典几乎是一种廉价的传输方式。

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

关于c# - WebApi 从 HttpActionContext 序列化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18322594/

相关文章:

c# - 鸭子类型(duck typing)在 C# 编译器中键入

c# - 跨语言编码标准

javascript - iPad 兼容的 HTML 所见即所得编辑器

javascript - knockout.js 可以绑定(bind)到 CSS 类吗?

c# - 我应该如何对异常类的序列化进行单元测试?

jquery - 将 JQuery 对象序列化为 JSON - 这应该可行吗?

c# - "Input string was not in a correct format."

c# - Entity Framework 的通用插入或更新

javascript - 将 UTC 字符串转换为 yyyy-mm-dd

ASP.NET VNext 类库 System.Runtime.Serialization