【问题标题】:Custom authorization with Azure AD Authentication in OWIN Web API在 OWIN Web API 中使用 Azure AD 身份验证进行自定义授权
【发布时间】:2015-09-05 06:39:07
【问题描述】:

我们正在为我们的一个客户端应用程序使用 Azure AD 身份验证。我们希望同时实现基于声明的授权。

我们的应用程序设置是基于 Angular 的客户端应用程序与 Web API 连接(两个客户端服务器都使用 Azure AD 承载身份验证进行保护)。服务器应用程序使用 OWIN 托管。

我们需要在服务器端提供自定义授权。 Azure AD 中有一项用于添加用户和角色的规定。然而,这对我们来说还不够。我们的用户管理是通过 AD 和安全组进行的。要获得对应用程序的访问权限,用户需要成为基本组的一部分,并且基于其他组分配更多权限(访问应用程序的特定部分、编辑特定实体等)或直接授予应用程序中的用户。本质上,并非所有用户都将在应用程序中注册,我们可能必须使用图形 API 查询 AD 以检查他们属于哪些所有应用程序特定组。

OWIN 身份验证和授权模型基于身份验证服务器和资源服务器。我们可以根据需要将它们分开。但是,在我们的例子中,我们需要拆分身份验证和授权。当客户端提供不记名令牌时,我们需要验证令牌是否有效,然后向用户配置文件添加声明。我们还需要缓存用户声明,这样我们就不会频繁地访问数据库。 (我们的客户端应用在一个用户操作中调用多个 Web API。)

Identity 2.0 中的位置在哪里

  1. 我可以验证令牌 &
  2. 插入特定于应用程序的声明

如果我的整个应用程序都围绕用户授权,并且所有查询都需要根据用户可以访问的数据进行过滤,那么哪种设计模式更适合 Web API 应用程序?

【问题讨论】:

  • 我不确定我是否完全理解了这个问题。您有一个使用承载身份验证的 Web api。您想如何使用 OAuthAuhorization?
  • 我想使用基于声明的授权。 OAuth 有很多示例,但不确定这是否适用于 Bearer auth。 Bearer 不使用 OAuth。
  • @ezile 请检查已编辑的问题。

标签: owin asp.net-identity-2 azure-active-directory asp.net-authorization


【解决方案1】:

我相信您正在寻找的是 ASP.NET Web API 2.0 堆栈中的身份验证和授权过滤器。

您可以通过在属性类上实现 System.Web.Http.Filters.IAuthorizationFilter 来实现按 Web 方法授权,然后使用该属性装饰服务控制器的 Web 操作方法。 Web API 2.0 将根据 URL 路由选择一个方法,请注意该方法上有一个实现 IAuthorizationFilter 的属性,并且会在调用该 Web 方法之前调用该属性实例上的 ExecuteAuthorizationFilterAsync 方法。将授权步骤放在 Web 方法调用之前可以快速丢弃无效请求,然后再进行繁重的参数绑定。

传入的令牌由在授权步骤之前执行的 IAuthenticationFilter 实现进行验证。

文档和示例很难找到。以下是少数几个真正相关的搜索结果之一:http://thegrumpycoder.com/post/105427070626/secure-web-services-with-web-api-and-sitecore

【讨论】:

    【解决方案2】:

    您可以检查这是否有帮助...

    UserProfile profile = new UserProfile(); //To deserialize the response stream (JSON)
            string tenantId = ClaimsPrincipal.Current.FindFirst(TenantIdClaimType).Value;
            AuthenticationResult result = null;
           try
            {
                // Get the access token from the cache
                string userObjectID =
                    ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")
                        .Value;
                AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID));
    //use ClientID, ClientSecret
                ClientCredential credential = new ClientCredential("b557ceed-xxxx-xxxx-xxxx-xxxxxxxbc240", "AXFxx//xxxxxxxxxxxxxjVFz4sqYm8NDAPEOLkU=");
                result = authContext.AcquireTokenSilent("https://graph.windows.net", credential,
                            new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
                // AcquireTokenSilent may throw exception if the cache is empty. In that case, logout the user and make him login.
                string requestUrl = String.Format(
                    CultureInfo.InvariantCulture,
                    "https://graph.windows.net/cdmsdev.onmicrosoft.com/groups/b40xxxx-14a8-xxxx-9559-xxxxxxca90c8/members/?api-version=1.6");
                //Above grap API url is for getting list of users who belong to a specific group (with GUID b40xxxx-1....)
    HttpClient client = new HttpClient();
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = client.SendAsync(request).Result;            
                if (response.IsSuccessStatusCode)
                {
                    var upn = ClaimsPrincipal.Current.Identity.Name;
                    string responseString = response.Content.ReadAsStringAsync().Result;
                    profile = JsonConvert.DeserializeObject<UserProfile>(responseString);
                    if (profile.Users.Contains(upn)) //check if the current user is in the list of users of the Admin group
                        return true;
                }
            }
            catch (Exception e)
            {
                //handle authorization exception here
            }
    

    图形 API URL 可以替换为检查特定组成员资格的函数,该函数将直接返回 bool 值,而不是获取该组的所有用户。

    【讨论】:

      猜你喜欢
      • 2018-05-19
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      • 2022-11-11
      • 2019-10-14
      • 1970-01-01
      • 2021-03-14
      相关资源
      最近更新 更多