【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 }
安全验证
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>
----------------------------------------------------------------------客户端-------------------------------------------------------------------------------------------
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 }
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