<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [WCF權限控制]WCF自定義授權體系詳解[實例篇]

      在《原理篇》中,我們談到WCF自定義授權體系具有兩個核心的組件:AuthorizationPolicy和ServiceAuthorizationManager,已經它們是如何寫作最終提供一種基于聲明的授權實現。為了讓自定義授權有深刻的理解,我們來進行一個簡單實例來演示如何通過自定義這兩個組件實現“非角色授權策略”。[源代碼從這里下載]

      目錄:
      一、創建演示程序解決方案
      二、自定義AuthorizationPolicy
      三、自定義ServiceAuthorizationManager
      四、應用自定義AuthorizationPolicy和ServiceAuthorizationManager

      一、創建演示程序解決方案

      。我們這個實例依然采用簡單的計算服務的例子,并且采用如下圖所示的解決方案結構。不過,為了后續的授權策略需要,我們在服務契約ICalculator接口上定義如下四個分別表示加、減、乘、除的四個運算操作。當然服務類型CalculatorService也進行相應的修正。

      image

      ICalculator:

         1: using System.ServiceModel;
         2: namespace Artech.WcfServices.Contracts
         3: {
         4:     [ServiceContract(Namespace = "http://www.artech.com/")]
         5:     public interface ICalculator
         6:     {
         7:         [OperationContract(Action = "http://www.artech.com/calculator/add")]
         8:         double Add(double x, double y);
         9:         [OperationContract(Action = "http://www.artech.com/calculator/subtract")]
        10:         double Subtract(double x, double y);
        11:         [OperationContract(Action = "http://www.artech.com/calculator/multiply")]
        12:         double Multiply(double x, double y);
        13:         [OperationContract(Action = "http://www.artech.com/calculator/divide")]
        14:         double Divide(double x, double y);
        15:     }
        16: }

      CalculatorService:

         1: using Artech.WcfServices.Contracts;
         2: namespace Artech.WcfServices.Services
         3: {
         4:     public class CalculatorService : ICalculator
         5:     {
         6:         public double Add(double x, double y)
         7:         {           
         8:             return x + y;
         9:         }
        10:         public double Subtract(double x, double y)
        11:         {
        12:             return x - y;
        13:         }
        14:         public double Multiply(double x, double y)
        15:         {
        16:             return x * y;
        17:         }
        18:         public double Divide(double x, double y)
        19:         {
        20:             return x / y;
        21:         }
        22:     }
        23: } 

      現在我們的授權策略是這樣的:操作Add和Subtract針對僅對用戶Foo開放,而Multiply和Divide操作僅對用戶Bar開放。雖然這個簡單的授權完全可以通過在相應的服務操作方法上應用PrincipalPermissionAttribute并指定Name屬性來實現。但是我們要嘗試通過自定義AuthorizationPolicy和ServiceAuthorizationManager來實現這樣的授權策略。先來看看自定義的AuthorizationPolicy的定義。

      二、自定義AuthorizationPolicy

      我們將自定義的AuthorizationPolicy創建在Hosting項目中。由于IAuthorizationPolicy定義在System.IdentityModel程序集中,我們先為Hosting項目添加該程序集的引用。由于授權策略比較簡單,我們直接上自定義的AuthorizationPolicy命名為SimpleAuthorizationPolicy,下面是整個SimpleAuthorizationPolicy的定義。

         1: using System;
         2: using System.Collections.Generic;
         3: using System.IdentityModel.Claims;
         4: using System.IdentityModel.Policy;
         5: using System.Linq;
         6: namespace Artech.WcfServices.Hosting
         7: {
         8:     public class SimpleAuthorizationPolicy : IAuthorizationPolicy
         9:     {
        10:         private const string ActionOfAdd = "http://www.artech.com/calculator/add";
        11:         private const string ActionOfSubtract = "http://www.artech.com/calculator/subtract";
        12:         private const string ActionOfMultiply = "http://www.artech.com/calculator/multiply";
        13:         private const string ActionOfDivide = "http://www.artech.com/calculator/divide";
        14:  
        15:         internal const string ClaimType4AllowedOperation = "http://www.artech.com/allowed";
        16:  
        17:         public SimpleAuthorizationPolicy()
        18:         {
        19:             this.Id = Guid.NewGuid().ToString();
        20:         }
        21:         public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        22:         {
        23:             if (null == state)
        24:             {
        25:                 state = false;
        26:             }
        27:             bool hasAddedClaims = (bool)state;
        28:             if (hasAddedClaims)
        29:             {
        30:                 return true; ;
        31:             }
        32:             IList<Claim> claims = new List<Claim>();
        33:             foreach (ClaimSet claimSet in evaluationContext.ClaimSets)
        34:             {
        35:                 foreach (Claim claim in claimSet.FindClaims(ClaimTypes.Name, Rights.PossessProperty))
        36:                 {
        37:                     string userName = (string)claim.Resource;
        38:                     if (userName.Contains('\\'))
        39:                     {
        40:                         userName = userName.Split('\\')[1];
        41:                         if (string.Compare("Foo", userName, true) == 0)
        42:                         {
        43:                             claims.Add(new Claim(ClaimType4AllowedOperation,ActionOfAdd, Rights.PossessProperty));
        44:                             claims.Add(new Claim(ClaimType4AllowedOperation, ActionOfSubtract, Rights.PossessProperty));
        45:                         }
        46:                         if (string.Compare("Bar", userName, true) == 0)
        47:                         {
        48:                             claims.Add(new Claim(ClaimType4AllowedOperation,ActionOfMultiply, Rights.PossessProperty));
        49:                             claims.Add(new Claim(ClaimType4AllowedOperation, ActionOfDivide, Rights.PossessProperty));
        50:                         }
        51:                     }
        52:                 }
        53:             }
        54:             evaluationContext.AddClaimSet(this, new DefaultClaimSet(this.Issuer, claims));
        55:             state = true;
        56:             return true;           
        57:         }
        58:         public ClaimSet Issuer
        59:         {
        60:             get { return ClaimSet.System; }
        61:         }
        62:         public string Id { get; private set; }
        63:     }
        64: }

      我們主要來介紹Evaluate方法中,該方法主要的邏輯是這樣的:通過EvaluationContext現有的聲明集獲取當前的用戶名(聲明類型和聲明權限分別為ClaimTypes.Name和Rights.PossessProperty)。針對獲取出來的用戶名,創建于被授權服務操作關聯的聲明。其中聲明的三要素(類型、權限和資源)分別為:“http://www.artech.com/allowed”、Rights.PossessProperty和操作的Action。最后將這些聲明組成一個聲明集添加到EvaluationContext中。

      三、自定義ServiceAuthorizationManager

      當授權相關的聲明集通過自定義的AuthorizationPolicy被初始化之后,我們通過自定義ServiceAuthorizationManager來分析這些聲明,并作做出當前操作是否被授權調用的最終判斷。類似于SimpleAuthorizationPolicy,我們將自定義的ServiceAuthorizationManager起名為SimpleServiceAuthorizationManager,同樣定義于Hosting項目中,下面是整個SimpleServiceAuthorizationManager類型的定義。

         1: using System.IdentityModel.Claims;
         2: using System.Security.Principal;
         3: using System.ServiceModel;
         4: namespace Artech.WcfServices.Hosting
         5: {
         6:     public class SimpleServiceAuthorizationManager : ServiceAuthorizationManager
         7:     {
         8:         protected override bool CheckAccessCore(OperationContext operationContext)
         9:         {
        10:             string action = operationContext.RequestContext.RequestMessage.Headers.Action;
        11:             foreach (ClaimSet claimSet in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
        12:             {
        13:                 if (claimSet.Issuer == ClaimSet.System)
        14:                 {
        15:                     foreach (Claim c in claimSet.FindClaims(SimpleAuthorizationPolicy.ClaimType4AllowedOperation, Rights.PossessProperty))
        16:                     {
        17:                         if (action == c.Resource.ToString())
        18:                         {
        19:                             GenericIdentity identity = new GenericIdentity("");
        20:                             operationContext.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] =
        21:                                 new GenericPrincipal(identity, null);
        22:                             return true;
        23:                         }
        24:                     }
        25:                 }
        26:             }
        27:             return false;            
        28:         }
        29:     }
        30: }

      由于基于被授權操作的聲明已經通過SimpleAuthorizationPolicy被成功添加到EvaluationContext的聲明集列表,并最終作為當前AuthorizationContext聲明集的一部分。那么,如果在這些代表被授權操作的聲明中,具有一個是基于當前被調用的服務操作的聲明,就意味著當前的服務操作調用被授權了的。這樣的邏輯實現在重寫的CheckAccessCore方法中。此外,還有一點需要注意的是:在做出成功授權的情況下,需要設置當前的安全主體,因為不管這個安全主體是否需要,WCF總是會試圖從當前AuthorizationContext的屬性列表中去獲取該安全主體。如果沒有,會拋出異常。

      四、應用自定義AuthorizationPolicy和ServiceAuthorizationManager

      到目前為止,兩個核心的自定義對象(SimpleAuthorizationPolicy和SimpleServiceAuthorizationManager)都已經創建好了,我們現在通過配置的方式將它們設置到應用到服務的ServiceAuthorizationBehavior服務行為上。下面兩段XML片斷分別表示服務寄宿和客戶端的配置。

      服務寄宿配置:

         1: <?xml version="1.0"?>
         2: <configuration>
         3:   <system.serviceModel>
         4:     <services>
         5:       <service name="Artech.WcfServices.Services.CalculatorService" behaviorConfiguration="useCustomAuthorization">

      6: <endpoint address="http://127.0.0.1/calculatorservice" binding="ws2007HttpBinding"

      contract="Artech.WcfServices.Contracts.ICalculator"/>

         7:       </service>
         8:     </services>
         9:     <behaviors>
        10:       <serviceBehaviors>
        11:         <behavior  name="useCustomAuthorization">         

      12: <serviceAuthorization principalPermissionMode="Custom"

      serviceAuthorizationManagerType="Artech.WcfServices.Hosting.SimpleServiceAuthorizationManager,Artech.WcfServices.Hosting">

        13:             <authorizationPolicies >
        14:               <add policyType="Artech.WcfServices.Hosting.SimpleAuthorizationPolicy, Artech.WcfServices.Hosting" />
        15:             </authorizationPolicies>
        16:           </serviceAuthorization>
        17:           <serviceDebug includeExceptionDetailInFaults="true"/>
        18:         </behavior>
        19:       </serviceBehaviors>
        20:     </behaviors>
        21:   </system.serviceModel>
        22: </configuration>

      客戶端配置:

         1: <?xml version="1.0"?>
         2: <configuration>
         3:   <system.serviceModel>
         4:     <client>

      5: <endpoint name="calculatorService" address="http://127.0.0.1/calculatorservice" binding="ws2007HttpBinding"

      contract="Artech.WcfServices.Contracts.ICalculator"/>

         6:     </client>  
         7:   </system.serviceModel>
         8: </configuration>

      我們最終需要驗證的WCF是否能夠按照我們自定義的策略進行授權。為了演示方便,我創建了如下一個名稱為Invoke的輔助方法。Invoke方法的三個參數分別代表進行服務調用的委托、服務代理對象和操作名稱。服務操作調用會在該方法中執行,并最終輸出相應的文字表示服務調用是否成功。

         1: static void Invoke(Action<ICalculator> action, ICalculator proxy, string operation)
         2: {
         3:     try
         4:     {
         5:         action(proxy);
         6:         Console.WriteLine("服務操作\"{0}\"調用成功...", operation);
         7:     }
         8:     catch (Exception ex)
         9:     {
        10:         Console.WriteLine("服務操作\"{0}\"調用失敗...", operation);
        11:     }
        12: }

      在如下的代碼中,我們分別以用戶名Foo和Bar的名義通過上面的Invoke輔助方法對計算服務的四個操作進行訪問。而程序執行的最終結果是和我們自定義的授權策略是一致的:用戶Foo僅僅授予了調用Add和Substract操作的權限,而其余兩個授權給用戶Bar。

         1: static void Main(string[] args)
         2: {
         3:     ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorService");
         4:     NetworkCredential credential = channelFactory.Credentials.Windows.ClientCredential;
         5:     credential.UserName = "Foo";
         6:     credential.Password = "Password";
         7:     ICalculator calculator = channelFactory.CreateChannel();
         8:     Invoke(proxy => proxy.Add(1, 2), calculator, "Add");
         9:     Invoke(proxy => proxy.Subtract(1, 2), calculator, "Subtract");
        10:     Invoke(proxy => proxy.Multiply(1, 2), calculator, "Multiply");
        11:     Invoke(proxy => proxy.Divide(1, 2), calculator, "Divide");
        12:     Console.WriteLine();
        13:  
        14:     channelFactory = new ChannelFactory<ICalculator>("calculatorService");
        15:     credential = channelFactory.Credentials.Windows.ClientCredential;
        16:     credential.UserName = "Bar";
        17:     credential.Password = "Password";
        18:     calculator = channelFactory.CreateChannel();
        19:     Invoke(proxy => proxy.Add(1, 2), calculator, "Add");
        20:     Invoke(proxy => proxy.Subtract(1, 2), calculator, "Subtract");
        21:     Invoke(proxy => proxy.Multiply(1, 2), calculator, "Multiply");
        22:     Invoke(proxy => proxy.Divide(1, 2), calculator, "Divide");
        23:  
        24:     Console.Read();
        25: }

      輸出結果:

         1: 服務操作"Add"調用成功...
         2: 服務操作"Subtract"調用成功...
         3: 服務操作"Multiply"調用失敗...
         4: 服務操作"Divide"調用失敗...
         5:  
         6: 服務操作"Add"調用失敗...
         7: 服務操作"Subtract"調用失敗...
         8: 服務操作"Multiply"調用成功...
         9: 服務操作"Divide"調用成功...

      [WCF權限控制]WCF自定義授權體系詳解[原理篇]
      [WCF權限控制]WCF自定義授權體系詳解[實例篇]

      posted @ 2011-07-11 22:16  Artech  閱讀(9620)  評論(16)    收藏  舉報
      主站蜘蛛池模板: 最新亚洲人成网站在线影院| 国产亚洲999精品AA片在线爽| 欧美三级中文字幕在线观看 | 大战丰满无码人妻50p| 久久精品国产色蜜蜜麻豆| 91精品乱码一区二区三区| 婷婷六月天在线| 免费观看添你到高潮视频| 精品乱人码一区二区二区| 亚洲国产成人综合精品| A毛片终身免费观看网站| 好爽毛片一区二区三区四| 日韩精品有码中文字幕| 影音先锋大黄瓜视频| 一区二区不卡99精品日韩| 国产成人一区二区三区视频免费| 欧美丰满熟妇乱XXXXX网站| 日韩高清国产中文字幕| 国产喷水1区2区3区咪咪爱AV| 精品人妻无码中文字幕在线| 91亚洲精品一区二区三区| 国产一区二区三区美女| 国产福利微视频一区二区| 国偷自产一区二区三区在线视频| 亚洲国产精品午夜福利| 日本一区二区三区在线播放| 99re在线视频观看| 99久久精品久久久久久婷婷| 少妇人妻av无码专区| 国产精品国三级国产专区| 久久精品一本到99热免费| 日本九州不卡久久精品一区| 98精品全国免费观看视频| 精品国产品香蕉在线| jizz视频在线观看| 午夜夜福利一区二区三区| 亚洲精品国产精品国自产| 成年午夜无码av片在线观看| 国产亚洲欧洲AⅤ综合一区| 成人午夜电影福利免费| 中文字幕国产精品日韩|