iw14.0.50来了,终于得直接以地点栏输入url打开iw功用页面了;可以擅自使用EasyUI等js框架了;展现形式对话框也不再七缠绕八缠绕惹人劳动了;

以身作则代码已经出狱!请移步拔取delphi+intraweb举办微信开发1~4代码示例进展下载,虽为示范代码不过是从自己种被改换出的,封装好齐全适于自行扩充和修改。

在《原理篇》中,大家提到WCF自定义授权体系具有两独基本之零部件:AuthorizationPolicy和瑟维斯(Service)AuthorizationManager,已经它们是何等做最终提供相同种基于讲明的授权实现。为了为于定义授权有深厚的了解,我们来拓展一个大概可靠例来演示如何通过从定义这半只零部件实现“非角色授权策略”。[源代码从这里下载]

 

目录:
同等、创设示范程序化解方案
二、自定义AuthorizationPolicy
三、自定义ServiceAuthorizationManager
季、应用由定义AuthorizationPolicy和ServiceAuthorizationManager

iw14.0.50来了,在新的版中极其吸引我之就是是多了圆满的httphandler功用:终于可以一向在地点栏输入url打开iw功用页面了;可以随心所欲使用EasyUI等js框架了;显示情势对话框也不再七纠缠八纠缠惹人劳了;呵呵,我感觉iw第一涂鸦接近主流web开发工具了!

一如既往、创制示范程序解决方案

。我们这多少个实例依然选择略的盘算服务之事例,并且以如下图所著之缓解方案结构。然而,为了持续的授权策略要,大家在劳动契约ICalculator接口上定义如下六只分级代表加、减、乘、除的季个运算操作。当然服务类型Calculator瑟维斯(Service)(Service)也进展对应的修正。

图片 1

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的概念。

兴奋了了,来尝试一下咔嚓。其实iw的坑依旧老多之,即使已八九不离十主流了,不过,前边渐渐还谋面说及…

二、自定义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: }

咱根本来介绍伊娃luate方法吃,该法要的逻辑是这样的:通过伊娃luationContext现有的阐明集获取当前的用户称(讲明类型和注解权限分别吗ClaimTypes.Name和Rights.PossessProperty)。针对获得出来的用户称,创建给吃授权服务操作关联的宣示。其中表明的三要素(类型、权限和资源)分别吗:“http://www.artech.com/allowed”、Rights.PossessProperty和操作的Action。最后将这些声明组成一个声明集添加到EvaluationContext中。

1、新建一个iw工程,选用Stand Alone Server /
Service 
,那种形式下进展付出是最为地道的,调试好有利,正式公布时得以还起一个library型的工程发布到.net服务器上。(是的,大家没有看错,现在iw已经脱离了isapi情势,可以像部署.net
mvc4应用相同安排及iis上,前边会讲,.net虚拟主机也可以宣布iw应用了!巨大的上进。)

三、自定义ServiceAuthorizationManager

当授权相关的宣示集通过由定义的AuthorizationPolicy被开头化之后,我们因而打定义Service(Service)AuthorizationManager来分析那么些表明,并作做出当前操作是否为授权调用的末梢判定。类似于SimpleAuthorizationPolicy,大家拿于定义的ServiceAuthorizationManager起名为Simple瑟维斯(Service)AuthorizationManager,同样定义为Hosting项目受到,上面是举Simple瑟维斯(Service)AuthorizationManager类型的定义。

   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被成功上加到伊娃(Eva)luationContext的扬言集列表,并最终作为当下AuthorizationContext注明集的一律组成部分。那么,要是在那个代表被授权操作的扬言中,具有一个凡冲当前深受调用的劳务操作的宣示,就意味着当前的劳动操作调用被授权了之。这样的逻辑实现以再度写的CheckAccessCore方法吃。其余,还有少数欲小心的是:在做出成功授权的场馆下,需要装当前底安全中央,因为无论这一个安全主旨是否要,WCF总是会总括从当下AuthorizationContext的性列表中错过得该安全中央。假诺没,会摈弃来好。

 

季、应用由定义AuthorizationPolicy和ServiceAuthorizationManager

至目前截止,两单核心的自定义对象(SimpleAuthorizationPolicy和Simple瑟维斯(Service)(Service)AuthorizationManager)都早就成立好了,我们现因而配备的主意拿其设置及下及服务之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自定义授权系列详解[实例篇]

2、封存工程后以工程被补充加一个初的单元文件,例如起名为wxapi.pas,这多少个文件被的代码用担微信接入工作。代码如下:

interface 

uses 
  Classes, IW.Content.Base, System.SysUtils,HTTPApp, IWApplication, 
  IW.HTTP.Request, IW.HTTP.Reply; 

type 
  /// <summary> 
  ///
于TContentBase继承下来的接近,就分外给asp.net中的httphandler
 
  /// </summary> 
  TWxApi = class(TContentBase) 
  protected 
    function Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication; aParams: TStrings): Boolean; override
  public 
    constructor Create; override
  end

implementation 

uses 
  ServerController, UserSessionUnit, Crypt.SHA1; 

{ TWxApi } 

constructor TWxApi.Create; 
begin 
  inherited
  // 文件不欲实际存在 
  FileMustExist := False; 
end

function TWxApi.Execute(aRequest: THttpRequest; aReply: THttpReply; 
  const aPathname: string; aSession: TIWApplication; 
  aParams: TStrings): Boolean; 
var 
  signature: string
  timestamp: string
  nonce: string
  echostr: string
  strs: TStringList; 
  tmpStr: string
begin 
  Result := True; 

  signature := aParams.Values[‘signature’]; 
  timestamp := aParams.Values[‘timestamp’]; 
  nonce := aParams.Values[‘nonce’]; 
  echostr := aParams.Values[‘echostr’]; 

  strs := TStringList.Create; 
  strs.Add(‘MyTestToken’);    // Token,要和微信接口配置信息保持一致 
  strs.Add(timestamp); 
  strs.Add(nonce); 
  strs.Sort; 

  tmpStr := strs[0]+strs[1]+strs[2]; 
  tmpStr := SHA1(AnsiString(tmpstr)); 

  

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图