WebAPI(MVC4)中的授权

时间:2014-04-08 14:12:03

标签: c# asp.net-web-api authorization basic-authentication restful-authentication

我的客户负责以下任务:

  

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

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

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

这一切都很有效。

我有一个名为Customer的控制器:

[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及其正确的auth标头,但在正文中他们传递了另一个用户ID
  5. 如何在方法级别阻止此操作?由于应用程序的不同部分触及某些控制器操作,我认为我无法保护所有这些操作。

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

2 个答案:

答案 0 :(得分:0)

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

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

就防止篡改请求进行一些研究。

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

答案 1 :(得分:0)

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