导出 (0) 打印
全部展开

如何:使用 WIF 和 ACS 在声明感知 ASP.NET 应用程序中实现声明授权

发布时间: 2011年4月

更新时间: 2011年5月

应用到: Windows Azure

适用于

  • Microsoft® Windows Azure™ AppFabric Access Control Service (ACS)

  • Windows® Identity Foundation (WIF)

  • ASP.NET

摘要

本主题介绍了如何使用 WIF 和 ACS 在声明感知 ASP.NET Web 应用程序中实现基于声明的访问控制 (CBAC) 授权。

内容

  • 目标

  • 概述

  • 步骤摘要

  • 步骤 1 – 实现声明授权库

  • 步骤 2 – 配置 ASP.NET 应用程序以使用声明授权库

  • 步骤 3 – 配置授权策略

  • 相关项

目标

  • 将授权逻辑与应用程序分开

  • 实现角色之外的授权检查,获得更精细的授权控制。

  • 为策略驱动和声明性的授权管理做准备。

概述

声明授权基于使用令牌内携带的信息 - 声明。当仅仅基于角色还不足以做出授权决定时,声明授权很有用。例如,在财务应用程序中,根据保有期和其他属性,可为同一个角色指定帐户间转移资金的不同限额。这类属性可以具有声明格式以及角色,因此可以实现更精细的授权决策。

步骤摘要

  • 步骤 1 – 实现声明授权库

  • 步骤 2 – 配置 ASP.NET 应用程序以使用声明授权库

  • 步骤 3 – 配置授权策略

步骤 1 – 实现声明授权库

此步骤向您展示了如何创建一个读取配置文件中的访问策略并执行访问检查的外部类库。以下示例展示了如何实现基于邮政编码声明做出授权决定的声明授权库。

实现声明授权库

  1. 请确保您是在管理员模式下运行 Visual Studio®。

  2. 在“解决方案资源管理器”中右键单击需要的解决方案,添加一个新的“类库”项目,然后为它指定名称,如 MyClaimsAuthorizationManager。

  3. 删除默认类 Class1.cs

  4. 添加一个新类并为它指定名称,如 ZipClaimsAuthorizationManager。这将实现基于邮政编码的授权。

  5. 添加对 Microsoft.IdentityModelSystem.Web 程序集的引用。

  6. 添加以下声明。

    using System.IO;
    using System.Xml; 
    using Microsoft.IdentityModel.Claims; 
    using Microsoft.IdentityModel.Configuration; 
    
    
  7. 扩展 ClaimsAuthorizationManager 类,覆盖其 AccessCheck 方法,然后实现 ZipClaimsAuthorizationManager 类的构造函数。您的代码应与下面的代码类似。

    namespace MyClaimsAuthorizationManager 
    { 
        class ZipClaimsAuthorizationManager : ClaimsAuthorizationManager 
        { 
            private static Dictionary<string, int> m_policies = new Dictionary<string, int>(); 
    
            public ZipClaimsAuthorizationManager(object config) 
            { 
                XmlNodeList nodes = config as XmlNodeList; 
                foreach (XmlNode node in nodes) 
                { 
                    { 
                        //FIND ZIP CLAIM IN THE POLICY IN WEB.CONFIG AND GET ITS VALUE 
                        //ADD THE VALUE TO MODULE SCOPE m_policies 
                        XmlTextReader reader = new XmlTextReader(new StringReader(node.OuterXml)); 
                        reader.MoveToContent(); 
                        string resource = reader.GetAttribute("resource"); 
                        reader.Read(); 
                        string claimType = reader.GetAttribute("claimType"); 
                        if (claimType.CompareTo(ClaimTypes.PostalCode) == 0) 
                        { 
                            throw new ArgumentNullException("Zip Authorization is not specified in policy in web.config"); 
                        } 
                        int zip = -1; 
                        bool success = int.TryParse(reader.GetAttribute("Zip"),out zip); 
                        if (!success) 
                        { 
                            throw new ArgumentException("Specified Zip code is invalid - check your web.config"); 
                        } 
                        m_policies[resource] = zip; 
                    } 
                } 
            } 
            public override bool CheckAccess(AuthorizationContext context) 
            { 
                //GET THE IDENTITY 
                //FIND THE POSTALCODE CLAIM'S VALUE IN IT 
                //COMPARE WITH THE POLICY 
                int allowedZip = -1; 
                int requestedZip = -1; 
                Uri webPage = new Uri(context.Resource.First().Value); 
                IClaimsPrincipal principal = (IClaimsPrincipal)HttpContext.Current.User; 
                if (principal == null) 
                { 
                    throw new InvalidOperationException("Principal is not populate in the context - check configuration"); 
                } 
                IClaimsIdentity identity = (IClaimsIdentity)principal.Identity; 
                if (m_policies.ContainsKey(webPage.PathAndQuery)) 
                { 
                    allowedZip = m_policies[webPage.PathAndQuery]; 
                    requestedZip = -1; 
                    int.TryParse((from c in identity.Claims 
                                            where c.ClaimType == ClaimTypes.PostalCode 
                                            select c.Value).FirstOrDefault(), out requestedZip); 
                } 
                if (requestedZip!=allowedZip) 
                { 
                    return false; 
                } 
                return true; 
            } 
        } 
    }
    
    
  8. 编译解决方案,以确保没有任何编译错误。

  9. 找到已编译的库,在本例中为 MyClaimsAuthorizationManager.dll。需要将它放至 ASP.NET Web 应用程序的 bin 文件夹中。

步骤 2 – 配置 ASP.NET 应用程序以使用声明授权库

后续步骤在您的 ASP.NET Web 应用程序中执行。不要添加对上一步创建的声明授权管理程序库的引用。您的 ASP.NET Web 应用程序应该“感知不到”它,除非在 web.config 中。

配置 ASP.NET 应用程序以使用声明授权库

  1. 通过在 web.config 中的 HttpModules 部分添加以下条目,配置您的 ASP.NET Web 应用程序以将 WIF ClaimsAuthorizationModule 包含在其管道中(对 Visual Studio 附带的开发 Web 服务器有效;对于 Internet 信息服务 (IIS) 7,此配置应位于 system.webServer 节点下方的模块部分。

    <add name="ClaimsAuthorizationModule" 
         type="Microsoft.IdentityModel.Web.ClaimsAuthorizationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
    
    
  2. 通过将以下条目添加到 microsoft.identityModel.service 节点,配置 ASP.NET Web 应用程序以使用上一步实现的自定义授权库。

    <claimsAuthorizationManager type="MyClaimsAuthorizationManager.ZipClaimsAuthorizationManager, MyClaimsAuthorizationManager" >
    
    

步骤 3 – 配置授权策略

在本主题中,配置策略在 ASP.NET Web 应用程序 web.config 文件中表示。该策略携带有将资源映射到声明类型及其值的简单规则。例如,以下策略可由前面的步骤中创建和配置的自定义授权库读取和执行。将以下条目添加到上一步配置的 calimsAuthorizationManager 节点。

<policy resource="/default.aspx">
  <claim claimType=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode
  Zip="11111" />
</policy>


以上策略要求传入令牌必须具有值为 11111 的 zip 声明才能访问 default.aspx 页。

相关项

显示:
© 2014 Microsoft