繁体   English   中英

WebAPI(MVC4)中的授权

[英]Authorization in WebAPI (MVC4)

我们的客户已为我安排了以下任务:

使其经过身份验证的用户无法修改其他用户的信息

当前,电话应用程序通过HTTPS向我们的API发送用户名和密码,作为BASIC身份验证标头:base64(username:password)。

在WebAPI中,我创建了BasicAuthenticationMessageHandler。 在此处理程序中,我针对客户LDAP验证用户凭据。

这一切都很好。

我有一个称为客户的控制器:

[Authorize]
public class CustomerController : BaseApiController<CustomerMapper>
{ ... }

我用如上所示的Authorize属性装饰它。

我有这样的PUT方法:

    public HttpResponseMessage Put(CustomerPutModel data)
    {
        if (ModelState.IsValid)
        {
            var c = customerService.GetByID(data.ID);

            if (c != null)
            {
                c = ModelMapper.Map<CustomerPutModel, Customer>(data, c);

                customerService.Update(c);

                return new HttpResponseMessage(HttpStatusCode.NoContent);
            }
        }
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest));
    }

模型:

public class CustomerPutModel
{
    public int ID{ get; set; }
    [Required]
    public string CustomerAccountID { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string City { get; set; }
    [Required]
    public string State { get; set; }
    public int Zipcode { get; set; }
}

此控制器方法按预期方式工作。

我遇到问题的地方是如何在我的PUT方法(以及所有其他控制器/方法)中防止以下情况:

  1. 用户1具有正确的身份验证凭据
  2. 用户1使用代理来监听请求
  3. 用户1将请求正文的ID从其ID更改为用户2的ID
  4. 用户1发送带有正确身份验证标头的PUT,但在正文中,他们传递了另一个用户ID

如何在方法级别防止这种情况? 由于应用程序的不同部分遇到了某些控制器操作,因此我认为我无法保护所有这些操作。

授权经过身份验证的用户实际上可以执行他们请求的操作的正确方法是什么? 是否需要为每个方法操作自定义编码?

我建议创建签名以验证请求是否被篡改,这意味着您根据应用程序发送的信息使用某种单向加密算法。

在API上收到请求时,只需使用相同的算法即可接收信息,并查看签名是否匹配。 如果不是,则有人篡改了请求并修改了一些信息。

只要进行一些防止篡改请求的研究即可。

关于确保用户只能执行某些方法而不能执行其他方法,例如,我建议您研究基于声明的授权。

您可以将Action方法更改为以下内容:

public HttpResponseMessage Put(CustomerPutModel data)
{
    if (ModelState.IsValid)
    {
        var myID = userService.GetIDByUserName(HttpContext.Current.User.Identity.Name);
        if (myID != data.ID) 
        {
            ... wrong id, e.g. throw an exception or return a View indicating the error.
        }
        var c = customerService.GetByID(data.ID);

        if (c != null)
        {
            c = ModelMapper.Map<CustomerPutModel, Customer>(data, c);

            customerService.Update(c);

            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM