如何解决 Web api 中的此安全漏洞
how to address this security breach in web api
我在基于 Web api 的项目中使用基于 OAuth 令牌的身份验证。
如果用户通过身份验证,将生成一个访问令牌,如下所示。
{"access_token":"FFz_DC6zzEDD4mGOCk9172ijj3sGxCUWnk-tGanm9wGk76hMB8sHI8ImeWtdUKHHGNXv465ZSlbb-3fr_hr9DqUHc9Dm9OBI7XjJhdjdOpAGAGSFOpE0Y17LCEWTjCmEZotuf42Mpgl81ewoS7OlnH4b5w4PrtzJbIBpSAMoWObziL_U3mTkeFKvWrcWOfvlSCvhhBA9Dc3UTXv3HiHKWQk0T3-pvVy7ZuW2oac-IIuaq_GYaVkIZh7s9-YjX9KAL2Z9yfrPrVOQXZe_5OcNd7nS3tdT5odchEAiuWRYQ6t7Tfb2si4T6VdAe73OYefE0se1FeQsxbOiNaLyF8OwBqymEUzEG8tEHJ-cejVbhPw","token_type":"bearer","expires_in":1799,"as:client_id":"","user":"1","role":"1",".issued":"Thu, 16 Feb 2017 09:37:44 GMT",".expires":"Thu, 16 Feb 2017 10:07:44 GMT"}
下面是api方法之一。
[Authorize]
[HttpGet]
[Route("{userId}/{type}/")]
public IHttpResponse GetCustomerDetails(int userId, string type)
{
//my api stuff
}
我正在使用 Postman 进行测试 api。当我将参数作为
传递时
http://localhost:50684/api/customer/1/gold
--along the access token in token in header--
它returns 想要的json。
但是如果我使用相同的令牌并传递客户 ID = 2,它仍然允许访问其他客户(ID = 2)。
http://localhost:50684/api/customer/2/gold
--Access token in header--
不应允许 id=2 的用户访问资源,因为生成的访问令牌对 id=1 的用户有效。
如何防止此安全漏洞?
任何 help/suggestion 高度赞赏。
谢谢
您可以将用户 ID 和令牌存储在某些存储(会话、数据库)中。
并编写自己的 MVC authorization fileter 类似 Authorize
过滤器,它将令牌与存储在存储中的用户 ID 进行比较。
目前WebApi不匹配user id和authenticated user's id的概念。它不应该,因为您唯一指定的是带有某些参数的控制器方法的路由。您只需要通过使用 "Authorize" 属性对用户进行身份验证,但是一旦授予访问权限,就不会再进行进一步的验证 运行。要使此方法仅对您的用户的特定子集可用,您可以编写自己的通用验证(即在这种情况下检查用户的声明,该声明可以在控制器范围内由 "User" 属性 访问,或使用一些 out-of-the-box 处理身份验证的外部实现。
问题是您将 userId 作为参数发送,这本身就是糟糕的设计。
简单的解决方案是从上下文中获取当前用户
[Authorize]
[HttpGet]
[Route("{type}/")]
public IHttpResponse GetCustomerDetails(string type)
{
var user = RequestContext.Principal.Identity.Name;
//my api stuff
}
我在基于 Web api 的项目中使用基于 OAuth 令牌的身份验证。
如果用户通过身份验证,将生成一个访问令牌,如下所示。
{"access_token":"FFz_DC6zzEDD4mGOCk9172ijj3sGxCUWnk-tGanm9wGk76hMB8sHI8ImeWtdUKHHGNXv465ZSlbb-3fr_hr9DqUHc9Dm9OBI7XjJhdjdOpAGAGSFOpE0Y17LCEWTjCmEZotuf42Mpgl81ewoS7OlnH4b5w4PrtzJbIBpSAMoWObziL_U3mTkeFKvWrcWOfvlSCvhhBA9Dc3UTXv3HiHKWQk0T3-pvVy7ZuW2oac-IIuaq_GYaVkIZh7s9-YjX9KAL2Z9yfrPrVOQXZe_5OcNd7nS3tdT5odchEAiuWRYQ6t7Tfb2si4T6VdAe73OYefE0se1FeQsxbOiNaLyF8OwBqymEUzEG8tEHJ-cejVbhPw","token_type":"bearer","expires_in":1799,"as:client_id":"","user":"1","role":"1",".issued":"Thu, 16 Feb 2017 09:37:44 GMT",".expires":"Thu, 16 Feb 2017 10:07:44 GMT"}
下面是api方法之一。
[Authorize]
[HttpGet]
[Route("{userId}/{type}/")]
public IHttpResponse GetCustomerDetails(int userId, string type)
{
//my api stuff
}
我正在使用 Postman 进行测试 api。当我将参数作为
传递时http://localhost:50684/api/customer/1/gold
--along the access token in token in header--
它returns 想要的json。
但是如果我使用相同的令牌并传递客户 ID = 2,它仍然允许访问其他客户(ID = 2)。
http://localhost:50684/api/customer/2/gold
--Access token in header--
不应允许 id=2 的用户访问资源,因为生成的访问令牌对 id=1 的用户有效。
如何防止此安全漏洞?
任何 help/suggestion 高度赞赏。
谢谢
您可以将用户 ID 和令牌存储在某些存储(会话、数据库)中。
并编写自己的 MVC authorization fileter 类似 Authorize
过滤器,它将令牌与存储在存储中的用户 ID 进行比较。
目前WebApi不匹配user id和authenticated user's id的概念。它不应该,因为您唯一指定的是带有某些参数的控制器方法的路由。您只需要通过使用 "Authorize" 属性对用户进行身份验证,但是一旦授予访问权限,就不会再进行进一步的验证 运行。要使此方法仅对您的用户的特定子集可用,您可以编写自己的通用验证(即在这种情况下检查用户的声明,该声明可以在控制器范围内由 "User" 属性 访问,或使用一些 out-of-the-box 处理身份验证的外部实现。
问题是您将 userId 作为参数发送,这本身就是糟糕的设计。
简单的解决方案是从上下文中获取当前用户
[Authorize]
[HttpGet]
[Route("{type}/")]
public IHttpResponse GetCustomerDetails(string type)
{
var user = RequestContext.Principal.Identity.Name;
//my api stuff
}