WebAPI(MVC4)中的授权

本文关键字:授权 MVC4 WebAPI | 更新日期: 2023-09-27 17:57:36

我们的客户委托我完成以下任务:

使其成为一个经过身份验证的用户不能修改另一个用户的信息

目前,手机应用程序通过HTTPS向我们的API发送用户用户名和密码,作为BASIC验证头:base64(用户名:密码)。

在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发送了一个带有正确auth头的PUT,但在正文中他们传递了另一个用户ID

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

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

WebAPI(MVC4)中的授权

您可以将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));
}

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

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

只需对防止篡改请求进行一些研究。

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