使用OWIN Web API中的Azure AD身份验证进行自定义授权

时间:2015-06-19 10:06:50

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

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

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

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

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

Identity 2.0中的位置

  1. 我可以验证令牌&
  2. 插入特定于应用程序的声明
  3. 如果我的整个应用程序围绕用户授权进行,并且需要对用户可以访问的数据进行过滤,这对于Web API应用程序来说是更合适的设计模式吗?

2 个答案:

答案 0 :(得分:0)

我相信您正在寻找的是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

答案 1 :(得分:0)

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

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 API,以检查特定组的成员身份,该组将直接返回bool值,而不是获取该组的所有用户。