【WCF安全】WCF 自定义授权[用户名+密码+x509证书]

1.x509证书制作(略)

2.直接贴代码

----------------------------------------------------------------------服务端-------------------------------------------------------------------------------------------

WCF服务

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Runtime.Serialization;
 5 using System.ServiceModel;
 6 using System.ServiceModel.Web;
 7 using System.Text;
 8 
 9 namespace WcfService自定义授权
10 {
11     
12     public class Service1 : IService1
13     {
14         public string GetData(int value)
15         {
16             return string.Format("You entered: {0}", value);
17         }
18 
19         public int GetNumber(int A, int B)
20         {
21             return A + B;
22         }
23 
24         public string GetStr(string str)
25         {
26             return "GetStr:" + str;
27         }
28     }
29 
30     [ServiceContract]
31     public interface IService1
32     {
33         [OperationContract]
34         string GetData(int value);
35         [OperationContract]
36         int GetNumber(int A, int B);
37         [OperationContract]
38         string GetStr(string str);
39     }
40 }
WCF服务

 

安全验证

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Xml;
 6 
 7 namespace WcfService自定义授权
 8 {
 9     /// <summary>
10     /// 实现自定义用户名密码校验
11     /// </summary>
12     public class MyCustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
13     {
14         public override void Validate(string userName, string password)
15         {
16             if (userName == null || password == null)
17             {
18                 throw new ArgumentNullException("用户名或密码不能为空");
19             }
20             if (!HelpCheckUserNamePassWord(userName, password))//(userName != "admin" && userName != "admin2")
21             {
22                 throw new ArgumentNullException("用户名或密码不正确");
23             }
24         }
25 
26         #region 私有方法
27         /// <summary>
28         /// 校验用户名密码
29         /// </summary>
30         /// <param name="userName">用户名</param>
31         /// <param name="passWord">密码</param>
32         /// <returns></returns>
33         private bool HelpCheckUserNamePassWord(string userName, string passWord)
34         {
35             List<string> list = new List<string>();
36             XmlDocument doc = new XmlDocument();
37             doc.Load(AppDomain.CurrentDomain.BaseDirectory + "SafetyVerification\\UserRoleConfig.xml");
38             XmlNodeList nodes = doc.SelectNodes("UserRoleConfig/User");
39             foreach (XmlNode node in nodes)
40             {
41                 string name = String.Empty;//用户名
42                 string pwd = String.Empty;//密码
43                 foreach (XmlAttribute xa in node.Attributes)//校验用户名密码
44                 {
45                     if (xa.Name == "Name" && xa.Value == userName)
46                         name = xa.Value;
47                     else if (xa.Name == "PassWord" && xa.Value == passWord)
48                         pwd = xa.Value;
49                     if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(pwd))
50                         return true;
51                 }
52             }
53             return false;
54         }
55         #endregion
56     }
57 }
校验用户名和密码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.ServiceModel;
 6 
 7 namespace WcfService自定义授权
 8 {
 9     /// <summary>
10     /// 提供对服务操作的授权访问检查
11     /// </summary>
12     public class CustomServiceAuthorizationManager : System.ServiceModel.ServiceAuthorizationManager
13     {
14         protected override bool CheckAccessCore(OperationContext operationContext)
15         {
16             //请求调用的资源url
17             string action = operationContext.RequestContext.RequestMessage.Headers.Action;
18             Console.ForegroundColor = ConsoleColor.Red;
19             Console.ForegroundColor = ConsoleColor.White;
20             //ClaimSet 表示与某个实体关联的声明的集合。
21             //获取与授权策略关联的声明集
22             foreach (System.IdentityModel.Claims.ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
23             {
24                 if (cs.Issuer == System.IdentityModel.Claims.ClaimSet.System)
25                 {
26                     foreach (System.IdentityModel.Claims.Claim claim in cs.FindClaims("http://tempuri.org/", System.IdentityModel.Claims.Rights.PossessProperty))
27                     {
28                         //校验是否有调用权限
29                         if (claim.Resource.ToString() == action)
30                         {
31                             return true;//通过
32                         }
33                         else
34                         {
35                             string url = action.Substring(0, action.LastIndexOf('/'));
36                             if (claim.Resource.ToString() == url + "/all")//可以调用该服务下所有的方法
37                                 return true;
38                         }
39                         
40                     }
41                 }
42             }
43             return false;//不通过
44         }
45     }
46 }
提供对服务操作的授权访问检查
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Web;
  5 using System.Xml;
  6 
  7 namespace WcfService自定义授权
  8 {
  9     /// <summary>
 10     /// 查询用户可调用的资源
 11     /// 定义一组用于对用户进行授权的规则
 12     /// </summary>
 13     public class CustomAuthorizationPolicy : System.IdentityModel.Policy.IAuthorizationPolicy
 14     {
 15         string id = string.Empty;
 16         public CustomAuthorizationPolicy()
 17         {
 18             id = new Guid().ToString();
 19         }
 20         public System.IdentityModel.Claims.ClaimSet Issuer
 21         {
 22             get { return System.IdentityModel.Claims.ClaimSet.System; }
 23         }
 24         public string Id
 25         {
 26             get { return id; }
 27         }
 28         /// <summary>
 29         /// 查询用户可调用的资源
 30         /// </summary>
 31         /// <param name="evaluationContext"></param>
 32         /// <param name="state"></param>
 33         /// <returns></returns>
 34         public bool Evaluate(System.IdentityModel.Policy.EvaluationContext evaluationContext, ref object state)
 35         {
 36             bool flag = false;
 37             bool r_state = false;
 38             if (state == null) { state = r_state; } else { r_state = Convert.ToBoolean(state); }
 39             if (!r_state)
 40             {
 41                 List<System.IdentityModel.Claims.Claim> claims = new List<System.IdentityModel.Claims.Claim>();
 42                 foreach (System.IdentityModel.Claims.ClaimSet cs in evaluationContext.ClaimSets)
 43                 {
 44                     foreach (System.IdentityModel.Claims.Claim claim in cs.FindClaims
 45                         (System.IdentityModel.Claims.ClaimTypes.Name, System.IdentityModel.Claims.Rights.PossessProperty))
 46                     {
 47                         foreach (string str in HelpGetServiceResourceByUserName(claim.Resource.ToString()))
 48                         {
 49                             //授权的资源
 50                             claims.Add(new System.IdentityModel.Claims.Claim("http://tempuri.org/", str, System.IdentityModel.Claims.Rights.PossessProperty));
 51                         }
 52                     }
 53                 }
 54                 evaluationContext.AddClaimSet(this, new System.IdentityModel.Claims.DefaultClaimSet(Issuer, claims)); r_state = true; flag = true;
 55             }
 56             else { flag = true; }
 57             return flag;
 58         }
 59 
 60         #region 私有方法
 61         /// <summary>
 62         /// 通过用户名密码获取资源列表
 63         /// </summary>
 64         /// <param name="userName">用户名</param>
 65         /// <returns></returns>
 66         private List<string> HelpGetRoleListBy(string userName)
 67         {
 68             List<string> list = new List<string>();
 69             XmlDocument doc = new XmlDocument();
 70             doc.Load(AppDomain.CurrentDomain.BaseDirectory + "SafetyVerification\\UserRoleConfig.xml");
 71             XmlNodeList nodes = doc.SelectNodes("UserRoleConfig/User");
 72             foreach (XmlNode node in nodes)
 73             {
 74                 string name = String.Empty;//用户名
 75                 foreach (XmlAttribute xa in node.Attributes)//校验用户名密码
 76                 {
 77                     if (xa.Name == "Name" && xa.Value == userName)
 78                     {
 79                         foreach (XmlNode xn in node.ChildNodes)//查询该用户拥有的角色
 80                         {
 81                             if (xn.Name != "Role")
 82                                 continue;
 83                             list.Add(xn.InnerXml);
 84                         }
 85                         break;
 86                     }
 87                 }
 88             }
 89             return list;
 90         }
 91         /// <summary>
 92         /// 通过用户名获取资源
 93         /// </summary>
 94         /// <param name="userName">用户名</param>
 95         /// <returns></returns>
 96         private IEnumerable<string> HelpGetServiceResourceByUserName(string userName)
 97         {
 98             List<string> lists = new List<string>();
 99             List<string> rlist = HelpGetRoleListBy(userName);
100             XmlDocument doc = new XmlDocument();
101             doc.Load(AppDomain.CurrentDomain.BaseDirectory + "SafetyVerification\\RoleResourceConfig.xml");
102             XmlNodeList nodes = doc.SelectNodes("ResourceConfig/Role");
103             foreach (XmlNode node in nodes)
104             {
105                 foreach (XmlAttribute xa in node.Attributes)
106                 {
107                     if (xa.Name == "Name" && rlist.Contains(xa.Value)) //查询角色下的所有资源
108                     {
109                         foreach (XmlNode xn in node.ChildNodes)
110                         {
111                             if (xn.Name == "Resource")
112                                 lists.Add(xn.InnerXml);
113                         }
114                         break;
115                     }
116                 }
117             }
118             return lists;
119         }
120         #endregion
121         
122     }
123 
124 }
定义一组用于对用户进行授权的规则

 

Xml配置文件

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <UserRoleConfig>
 3   <User Name="ptadmin" PassWord="pt8008" >
 4     <Role>Dictionary</Role>
 5     <Role>PlatForm</Role>
 6   </User>
 7   <User Name="webadmin" PassWord="web8010" >
 8     <Role>Dictionary</Role>
 9     <Role>WebSite</Role>
10   </User>
11   <User Name="eadmin" PassWord="e8011" >
12     <Role>EnterpriseLibrary</Role>
13   </User>
14 </UserRoleConfig>
配置用户和角色

 

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <ResourceConfig>
 3 
 4   <Role Name="Dictionary">
 5     <!--格式:地址+方法名;all表示有权限访问该地址下所有的服务方法-->
 6     <Resource>http://tempuri.org/IService1/all</Resource>
 7   </Role>
 8  
 9   <Role Name="PlatForm">
10     <Resource>http://tempuri.org/IService1/all</Resource>
11     <Resource>http://tempuri.org/IService1/all2</Resource>
12     <Resource>http://tempuri.org/IService1/all3</Resource>
13   </Role>
14 
15   <Role Name="WebSite">
16     <Resource>http://tempuri.org/IService1/all</Resource>
17   </Role>
18   
19   <Role Name="EnterpriseLibrary">
20     <Resource>http://tempuri.org/IService1/all</Resource>
21   </Role>
22 </ResourceConfig>
配置角色和资源

 

web.Config配置文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <configuration>
 3   <system.web>
 4     <compilation debug="true" targetFramework="4.0" />
 5   </system.web>
 6   <system.serviceModel>
 7     <services>
 8       <service name="WcfService自定义授权.Service1" behaviorConfiguration="httpBehavior">
 9         <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsBinding" 
10                   contract="WcfService自定义授权.IService1">
11           <identity>
12             <dns value="JRNet01-PC" />
13           </identity>
14         </endpoint>
15         <host>
16           <baseAddresses>
17             <add baseAddress="http://JRNet01-PC:7794"/>
18           </baseAddresses>
19         </host>
20       </service>
21     </services>
22     <bindings>
23       <wsHttpBinding>
24         <binding name="wsBinding">
25           <security mode="Message">
26             <message clientCredentialType="UserName"/>
27           </security>
28         </binding>
29       </wsHttpBinding>
30     </bindings>
31     <behaviors>
32       <serviceBehaviors>
33         <behavior name="httpBehavior">
34           <serviceMetadata httpGetEnabled="true"/>
35           <serviceCredentials>
36             <serviceCertificate findValue="JRNet01-PC" x509FindType="FindBySubjectName" storeLocation="LocalMachine" 
37                                 storeName="My" />
38             <userNameAuthentication userNamePasswordValidationMode="Custom" 
39                                     customUserNamePasswordValidatorType="WcfService自定义授权.MyCustomUserNameValidator,WcfService自定义授权"/>
40             <clientCertificate>
41               <!--自定义对客户端进行证书认证方式 这里为 None-->
42               <authentication certificateValidationMode="Custom"/>
43             </clientCertificate>
44           </serviceCredentials>
45           <serviceAuthorization serviceAuthorizationManagerType="WcfService自定义授权.CustomServiceAuthorizationManager,WcfService自定义授权">
46             <authorizationPolicies>
47               <add policyType="WcfService自定义授权.CustomAuthorizationPolicy,WcfService自定义授权"/>
48             </authorizationPolicies>
49           </serviceAuthorization>
50         </behavior>
51       </serviceBehaviors>
52     </behaviors>
53   </system.serviceModel>
54   <system.webServer>
55     <modules runAllManagedModulesForAllRequests="true"/>
56   </system.webServer>
57 </configuration>
Web.Config

 

----------------------------------------------------------------------客户端-------------------------------------------------------------------------------------------

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace WCF自定义授权TestClient
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             try
13             {
14                 ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
15                 sc.ClientCredentials.UserName.UserName = "admin";
16                 sc.ClientCredentials.UserName.Password = "123456789";
17                 string result = sc.GetStr("asdfg");
18                 Console.WriteLine(result);
19             }
20             catch (Exception ex)
21             {
22                 Console.WriteLine(ex.Message);
23             }
24             Console.ReadLine();
25         }
26     }
27 }
Program-Main
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <system.serviceModel>
 4     <bindings>
 5       <wsHttpBinding>
 6         <binding name="WSHttpBinding_IService1">
 7           <security>
 8             <message clientCredentialType="UserName" />
 9           </security>
10         </binding>
11       </wsHttpBinding>
12     </bindings>
13     <behaviors>
14       <endpointBehaviors>
15         <behavior name="myClientBehavior">
16           <clientCredentials>
17             <!--客户端证书-->
18             <clientCertificate findValue="JRNet01-PC" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
19             <serviceCertificate>
20               <authentication certificateValidationMode="None"/>
21             </serviceCertificate>
22           </clientCredentials>
23         </behavior>
24       </endpointBehaviors>
25     </behaviors>
26     <client>
27       <endpoint address="http://netnetnet-pc:5003/Service1.svc" binding="wsHttpBinding"
28           bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
29           name="WSHttpBinding_IService1"  behaviorConfiguration="myClientBehavior">
30         <identity>
31           <dns value="JRNet01-PC" />
32         </identity>
33       </endpoint>
34     </client>
35   </system.serviceModel>
36 </configuration>
配置文件

 

源码下载:WcfService自定义授权.rar

posted @ 2014-12-16 14:40  J.Y  阅读(260)  评论(0编辑  收藏  举报