我们的Web API将要求API的使用者提供我们分配给他们的API密钥。 API密钥将用于授权,并将用于添加数据(某处,某种程度上),以便ApiController的方法可以访问它们。
我正在考虑创建一个
的AuthorizationAttribute在我的dummied-up自定义AuthorizationAttribute中,如果授权成功,我通过执行以下操作将clientId和clientName添加到当前请求中:
actionContext.Request.Properties.add("clientId", 1234);
actionContext.Request.Properties.add("clientName", "Super Client");
然后在ApiController的一个方法中,我使用:
获取数据int clientId = (int)Request.Properties["clientId"];
string clientName = (string)Request.Properties["clientName"];
这有效,但它假设{client}中存在“clientId”和“clientName”。我们可以使用Request.Properties
进行检查,但我不想在Web API的每个方法中重复此检查代码。我想我可以有另一个属性进行检查,如果它无法在Request.Properties.ContainsKey
中找到它们,则返回500内部服务器错误(错误请求400?)。
或者我们可以让AuthorizationAttribute执行授权,然后在每个ApiController方法中进行一次调用 - 返回一个Client对象,其中包含在JSON有效负载中提供的API密钥所需的数据。此时我们知道API密钥有效,因此我们将获得控制器处理请求所需的数据。
我们的ApiController方法将数据添加到Request for access的推荐方法是什么?所需的数据,但基于提供的有效API密钥(我们将从数据库中获取数据,或者将其编码到公共API密钥中并在我们的服务器上解码)。那会:
我们正在运行Visual Studio 2010,MVC 4,.NET 4.API密钥将作为JSON有效负载的一部分提供给Web API。
魔法弦将消失; - )
答案 0 :(得分:0)
一种方法是为您的客户端提供公共共享密钥和私钥。对于每个发出的请求,客户端都需要将其公钥作为参数包括到期日期。到期日期的原因是,对其授权令牌有贡献的值将根据请求而变化。由于客户端将知道他们试图访问的资源并使其公钥有用,因此他们只需要确保他们发送的到期日期在服务器认为时间在utc内的容差阈值内。服务器和客户端都可以使用这些值及其假定的私钥创建安全哈希。然后,您可以验证发出请求的客户端>公钥是否是他们通过使用其私钥解密邮件的人。
每个传入消息都需要签名。如果在查询字符串上理论上它看起来像这样的注释:你也可以使用http标题:
Signature=<UrlEncode(Base64(HMAC-MD5(LowerCase( AbsolutePath(ResourceURL)) + UTCDate(ExpirationDate,“yyyyMMddHHmmss”)))> &Expires=<UTCDate(ExpirationDate ,“yyyyMMddHHmmss”)>&AccessKey=<PublicAccessKey>
对于您定义的每个需要授权的安全方法,如果哈希值有效,您可以让调用通过,否则返回未经授权的http状态代码。
答案 1 :(得分:0)
我建议使用MessageHandler,而不是使用ActionFilters。 MessageHandler可以查看请求,提取ClientId和ClientName(如果它们在那里)并将它们添加到属性中。然后在您需要提取该信息的控制器中,您可以使用ApiController扩展方法来访问controller.Request.Properties。这将封装你所有的魔法字符串。
我还建议将APIKey放在Authorization标头中,而不是放在JSON有效负载中,因为这正是Authorization标头的设计目的。