Asp.net web api json负载中带有令牌的WebApi授权筛选器

Asp.net web api json负载中带有令牌的WebApi授权筛选器,asp.net-web-api,Asp.net Web Api,我一直在研究AspNetWebApi的授权,关于这个主题的信息有点稀少 我有以下选择: 在查询字符串上传递API标记 将API令牌作为头传递 使用基本身份验证传递API令牌 以json格式将API令牌传递到请求负载上 通常推荐哪种方法 我还想知道第4点),我如何在AuthorizationFilterAttribute上的OnAuthorization方法中检查json负载,以检查API令牌是否正确?如果您想要一个真正安全的授权选项,可以使用OAuth之类的方法。这提供了一个使用现在已经过时的W

我一直在研究AspNetWebApi的授权,关于这个主题的信息有点稀少

我有以下选择:

  • 在查询字符串上传递API标记
  • 将API令牌作为头传递
  • 使用基本身份验证传递API令牌
  • 以json格式将API令牌传递到请求负载上
  • 通常推荐哪种方法


    我还想知道第4点),我如何在AuthorizationFilterAttribute上的OnAuthorization方法中检查json负载,以检查API令牌是否正确?

    如果您想要一个真正安全的授权选项,可以使用OAuth之类的方法。这提供了一个使用现在已经过时的WCFWebAPI的非常全面的示例,但是很多代码是可以修复的。或者至少,使用HTTP基本身份验证,如本文所示。正如Aliostad所指出的,如果您使用基本身份验证路由,请确保您使用的是HTTPS,以便令牌保持安全

    如果您决定自己滚动(几乎总是比上面的任何一个选项都安全得多),那么下面是一个代码示例,说明如果您选择HTTP头路由,您将需要授权handler。请注意,Web API类中处理UserPrinicipal的方式很可能会发生变化,因此此代码仅适用于第一个预览版本。您需要像这样连接AuthorizationHandler:

        GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthenticationHandler());
    
    头令牌的代码:

    public class AuthenticationHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            var requestAuthTokenList = GetRequestAuthTokens(request);
            if (ValidAuthorization(requestAuthTokenList))
            {
                //TODO: implement a Prinicipal generator that works for you
                var principalHelper = GlobalConfiguration.Configuration
                    .ServiceResolver
                        .GetService(typeof(IPrincipalHelper)) as IPrincipalHelper;
    
                request.Properties[HttpPropertyKeys.UserPrincipalKey] = 
                    principalHelper.GetPrinicipal(request);
    
                return base.SendAsync(request, cancellationToken);
            }
            /*
            ** This will make the whole API protected by the API token.
            ** To only protect parts of the API then mark controllers/methods
            ** with the Authorize attribute and always return this:
            **
            ** return base.SendAsync(request, cancellationToken);
            */
            return Task<HttpResponseMessage>.Factory.StartNew(
                () => new HttpResponseMessage(HttpStatusCode.Unauthorized)
                    {
                        Content = new StringContent("Authorization failed")
                    });
        }
    
        private static bool ValidAuthorization(IEnumerable<string> requestAuthTokens)
        {
            //TODO: get your API from config or however makes sense for you
            var apiAuthorizationToken = "good token";
            var authorized = requestAuthTokens.Contains(apiAuthorizationToken);
    
            return authorized;
        }
    
        private static IEnumerable<string> GetRequestAuthTokens(HttpRequestMessage request)
        {
            IEnumerable<string> requestAuthTokens;
            if (!request.Headers.TryGetValues("SomeHeaderApiKey", out requestAuthTokens))
            {
                //Initialize list to contain a single not found token:
                requestAuthTokens = new[] {"No API token found"};
            }
            return requestAuthTokens;
        }
    }
    
    公共类AuthenticationHandler:DelegatingHandler
    {
    受保护的覆盖任务SendAsync(
    HttpRequestMessage请求,
    取消令牌(取消令牌)
    {
    var requestAuthTokenList=GetRequestAuthTokens(请求);
    if(有效授权(requestAuthTokenList))
    {
    //TODO:实现一个适用于您的Prinicipal生成器
    var principalHelper=GlobalConfiguration.Configuration
    .ServiceResolver
    .GetService(类型为(IPrincipalHelper))作为IPrincipalHelper;
    request.Properties[HttpPropertyKeys.UserPrincipalKey]=
    principalHelper.GetPrinicipal(请求);
    返回base.sendaync(请求、取消令牌);
    }
    /*
    **这将使整个API受到API令牌的保护。
    **要仅保护部分API,请标记控制器/方法
    **使用Authorize属性,并始终返回以下内容:
    **
    **返回base.sendaync(请求、取消令牌);
    */
    return Task.Factory.StartNew(
    ()=>新的HttpResponseMessage(HttpStatusCode.Unauthorized)
    {
    内容=新的StringContent(“授权失败”)
    });
    }
    私有静态布尔有效授权(IEnumerable requestAuthTokens)
    {
    //TODO:从配置中获取API,或者以对您有意义的方式获取API
    var apiaauthorizationtoken=“良好的代币”;
    var authorized=requestAuthTokens.Contains(apiAuthorizationToken);
    授权返回;
    }
    私有静态IEnumerable GetRequestAuthTokens(HttpRequestMessage请求)
    {
    IEnumerable requestAuthTokens;
    if(!request.Headers.TryGetValues(“SomeHeaderApiKey”,out requestAuthTokens))
    {
    //初始化列表以包含单个未找到令牌:
    requestAuthTokens=new[]{“未找到API令牌”};
    }
    返回令牌;
    }
    }
    
    API令牌是什么意思?你是说认证cookie吗?只是一个可以在每个请求中传递的GUID来认证客户端。绝对正确,Aliostad!它根深蒂固,我甚至忘了提它。谢谢在标头中传递令牌或使用基本身份验证之间是否存在任何缺点?将API令牌与请求放在json中是否是不允许的?还有,主体生成器是如何工作的?我想说,分离关注点是我不将授权令牌放在json主体中的原因。如果您将它放在主体中,它可能是序列化到模型中的内容的一部分。如果这就是你想要的,那就去做吧。