【问题标题】:How to manage security over web methods using Web API?如何使用 Web API 管理 Web 方法的安全性?
【发布时间】:2017-05-23 08:46:20
【问题描述】:

我的场景如下:

我已经为移动应用创建了 WEB API。

  • TOKEN CALL - 它返回授权令牌成功和裸令牌 详情
  • GetCompanyDetails(int loginId)
  • GetCompanyCustomer(int companyId)

我在数据库中有如下表:

登录表:

ID| Username | Password | UserType | CreatedDate
1 | Alex | P#ssword | Company  | 2017-05-04
2 | Jhon | 4548@sd  | Company  | 2017-05-10
3 | Rubby | R#$S3343| Customer | 2017-05-11
4 | Moris | M#$353  | Customer | 2017-05-11
5 | Febio | Feb@153  | Customer | 2017-05-11 

公司详情表:

ID | LoginID | CompanyName | Address | CreatedDate | Location
5  |  1      | ALEX Company| Street 1| 2017-05-04  | USA
7  |  2      | JHON INC    | NJ, OPP PR market| 2017-05-10 | USA

客户详细信息表:

ID | LoginID | Address   | CreatedDate | Location
10  |  3      | Address 1| 2017-05-11  | USA
12  |  4      | Address 2| 2017-05-11 | USA
13  |  5      | Address 3| 2017-05-11 | USA

CompanyCustomer 表:

ID | CompanyID | CustomerID
1  |  5        | 10
1  |  5        | 12
2  |  7        | 13

一旦我授权了 API,然后我调用该方法来获取公司客户。 那个时候我通过 companyID 来获取客户..

[HttpGet]
[Authorize(Roles=("Company")]
public List<Customer> CompanyCustomer(int companyId)
{
 //Return the list of customer by companyId

}

我的观点是如何在 Token 授权时验证用户是否为同一用户。
假设我要求

  • ALEX 公司的 CompanyID = 5 然后我将其称为 CompanyCustomer(5) 将退回所有客户
  • 之后应该调用 companyCustomer(7) 然后它仍然返回另一家公司的所有客户。

    如何通过请求的用户检测 API 调用者令牌?

如何处理这种安全性?

【问题讨论】:

  • 您正在寻找的是Claim Authorization。 Here 你可能会发现一个使用 ASP.NET Identity 的示例。即使不使用 ASP.NET Identity,原理也是一样的。

标签: c# asp.net-web-api authorization token


【解决方案1】:
public sealed class PrivateAttribute : Attribute, IAuthorizationFilter {
    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation) {
        var claimsPrincipal = actionContext.RequestContext.Principal as ClaimsPrincipal;
        if (actionContext.RequestContext.RouteData.Values.ContainsKey(CONSTANTS.USER_ID_KEY) && claimsPrincipal != null) {
            var requestedID = actionContext.RequestContext.RouteData.Values[CONSTANTS.USER_ID_KEY];
            if (claimsPrincipal.HasClaim(CONSTANTS.USER_ID_KEY, requestedID.ToString())) {
                return continuation();
            } else { // someone is trying to get resources of another user
                return whatever fail;
            }
        } else { // there is no {id} paramter in the route, nothing to do
            return continuation();
        }
    }

    public bool AllowMultiple => false;
}

而在认证的时候:

public override async Task GrantResourceOwnerCredentials(
        OAuthGrantResourceOwnerCredentialsContext context) {
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
        using (var authRepo = AuthRepository.Create()) {
            var findUserResult = await authRepo.FindUser(context.UserName, context.Password);
            if (findUserResult == UserModel.NoUser) {
                context.SetError("error", "User not found.");
            } else {
                var identity = new ClaimsIdentity(context.Options.AuthenticationType);
                identity.AddClaim( // this is important, [PrivateAttribute] relies on this
                    new Claim(CONSTANTS.USER_ID_KEY, findUserResult.ID.ToString()));
                context.Validated(identity);
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 2014-05-03
    相关资源
    最近更新 更多