【WCF安全】WCF 自定义授权[用户名+密码+x509证书]
1.x509证书制作(略)
2.直接贴代码
----------------------------------------------------------------------服务端-------------------------------------------------------------------------------------------
WCF服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text; namespace WcfService自定义授权
{ public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
} public int GetNumber(int A, int B)
{
return A + B;
} public string GetStr(string str)
{
return "GetStr:" + str;
}
} [ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
int GetNumber(int A, int B);
[OperationContract]
string GetStr(string str);
}
}
WCF服务
安全验证
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml; namespace WcfService自定义授权
{
/// <summary>
/// 实现自定义用户名密码校验
/// </summary>
public class MyCustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName == null || password == null)
{
throw new ArgumentNullException("用户名或密码不能为空");
}
if (!HelpCheckUserNamePassWord(userName, password))//(userName != "admin" && userName != "admin2")
{
throw new ArgumentNullException("用户名或密码不正确");
}
} #region 私有方法
/// <summary>
/// 校验用户名密码
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="passWord">密码</param>
/// <returns></returns>
private bool HelpCheckUserNamePassWord(string userName, string passWord)
{
List<string> list = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load(AppDomain.CurrentDomain.BaseDirectory + "SafetyVerification\\UserRoleConfig.xml");
XmlNodeList nodes = doc.SelectNodes("UserRoleConfig/User");
foreach (XmlNode node in nodes)
{
string name = String.Empty;//用户名
string pwd = String.Empty;//密码
foreach (XmlAttribute xa in node.Attributes)//校验用户名密码
{
if (xa.Name == "Name" && xa.Value == userName)
name = xa.Value;
else if (xa.Name == "PassWord" && xa.Value == passWord)
pwd = xa.Value;
if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(pwd))
return true;
}
}
return false;
}
#endregion
}
}
校验用户名和密码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel; namespace WcfService自定义授权
{
/// <summary>
/// 提供对服务操作的授权访问检查
/// </summary>
public class CustomServiceAuthorizationManager : System.ServiceModel.ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
//请求调用的资源url
string action = operationContext.RequestContext.RequestMessage.Headers.Action;
Console.ForegroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
//ClaimSet 表示与某个实体关联的声明的集合。
//获取与授权策略关联的声明集
foreach (System.IdentityModel.Claims.ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
{
if (cs.Issuer == System.IdentityModel.Claims.ClaimSet.System)
{
foreach (System.IdentityModel.Claims.Claim claim in cs.FindClaims("http://tempuri.org/", System.IdentityModel.Claims.Rights.PossessProperty))
{
//校验是否有调用权限
if (claim.Resource.ToString() == action)
{
return true;//通过
}
else
{
string url = action.Substring(, action.LastIndexOf('/'));
if (claim.Resource.ToString() == url + "/all")//可以调用该服务下所有的方法
return true;
} }
}
}
return false;//不通过
}
}
}
提供对服务操作的授权访问检查
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml; namespace WcfService自定义授权
{
/// <summary>
/// 查询用户可调用的资源
/// 定义一组用于对用户进行授权的规则
/// </summary>
public class CustomAuthorizationPolicy : System.IdentityModel.Policy.IAuthorizationPolicy
{
string id = string.Empty;
public CustomAuthorizationPolicy()
{
id = new Guid().ToString();
}
public System.IdentityModel.Claims.ClaimSet Issuer
{
get { return System.IdentityModel.Claims.ClaimSet.System; }
}
public string Id
{
get { return id; }
}
/// <summary>
/// 查询用户可调用的资源
/// </summary>
/// <param name="evaluationContext"></param>
/// <param name="state"></param>
/// <returns></returns>
public bool Evaluate(System.IdentityModel.Policy.EvaluationContext evaluationContext, ref object state)
{
bool flag = false;
bool r_state = false;
if (state == null) { state = r_state; } else { r_state = Convert.ToBoolean(state); }
if (!r_state)
{
List<System.IdentityModel.Claims.Claim> claims = new List<System.IdentityModel.Claims.Claim>();
foreach (System.IdentityModel.Claims.ClaimSet cs in evaluationContext.ClaimSets)
{
foreach (System.IdentityModel.Claims.Claim claim in cs.FindClaims
(System.IdentityModel.Claims.ClaimTypes.Name, System.IdentityModel.Claims.Rights.PossessProperty))
{
foreach (string str in HelpGetServiceResourceByUserName(claim.Resource.ToString()))
{
//授权的资源
claims.Add(new System.IdentityModel.Claims.Claim("http://tempuri.org/", str, System.IdentityModel.Claims.Rights.PossessProperty));
}
}
}
evaluationContext.AddClaimSet(this, new System.IdentityModel.Claims.DefaultClaimSet(Issuer, claims)); r_state = true; flag = true;
}
else { flag = true; }
return flag;
} #region 私有方法
/// <summary>
/// 通过用户名密码获取资源列表
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
private List<string> HelpGetRoleListBy(string userName)
{
List<string> list = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load(AppDomain.CurrentDomain.BaseDirectory + "SafetyVerification\\UserRoleConfig.xml");
XmlNodeList nodes = doc.SelectNodes("UserRoleConfig/User");
foreach (XmlNode node in nodes)
{
string name = String.Empty;//用户名
foreach (XmlAttribute xa in node.Attributes)//校验用户名密码
{
if (xa.Name == "Name" && xa.Value == userName)
{
foreach (XmlNode xn in node.ChildNodes)//查询该用户拥有的角色
{
if (xn.Name != "Role")
continue;
list.Add(xn.InnerXml);
}
break;
}
}
}
return list;
}
/// <summary>
/// 通过用户名获取资源
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
private IEnumerable<string> HelpGetServiceResourceByUserName(string userName)
{
List<string> lists = new List<string>();
List<string> rlist = HelpGetRoleListBy(userName);
XmlDocument doc = new XmlDocument();
doc.Load(AppDomain.CurrentDomain.BaseDirectory + "SafetyVerification\\RoleResourceConfig.xml");
XmlNodeList nodes = doc.SelectNodes("ResourceConfig/Role");
foreach (XmlNode node in nodes)
{
foreach (XmlAttribute xa in node.Attributes)
{
if (xa.Name == "Name" && rlist.Contains(xa.Value)) //查询角色下的所有资源
{
foreach (XmlNode xn in node.ChildNodes)
{
if (xn.Name == "Resource")
lists.Add(xn.InnerXml);
}
break;
}
}
}
return lists;
}
#endregion } }
定义一组用于对用户进行授权的规则
Xml配置文件
<?xml version="1.0" encoding="utf-8" ?>
<UserRoleConfig>
<User Name="ptadmin" PassWord="pt8008" >
<Role>Dictionary</Role>
<Role>PlatForm</Role>
</User>
<User Name="webadmin" PassWord="web8010" >
<Role>Dictionary</Role>
<Role>WebSite</Role>
</User>
<User Name="eadmin" PassWord="e8011" >
<Role>EnterpriseLibrary</Role>
</User>
</UserRoleConfig>
配置用户和角色
<?xml version="1.0" encoding="utf-8" ?>
<ResourceConfig> <Role Name="Dictionary">
<!--格式:地址+方法名;all表示有权限访问该地址下所有的服务方法-->
<Resource>http://tempuri.org/IService1/all</Resource>
</Role> <Role Name="PlatForm">
<Resource>http://tempuri.org/IService1/all</Resource>
<Resource>http://tempuri.org/IService1/all2</Resource>
<Resource>http://tempuri.org/IService1/all3</Resource>
</Role> <Role Name="WebSite">
<Resource>http://tempuri.org/IService1/all</Resource>
</Role> <Role Name="EnterpriseLibrary">
<Resource>http://tempuri.org/IService1/all</Resource>
</Role>
</ResourceConfig>
配置角色和资源
web.Config配置文件
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService自定义授权.Service1" behaviorConfiguration="httpBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsBinding"
contract="WcfService自定义授权.IService1">
<identity>
<dns value="JRNet01-PC" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://JRNet01-PC:7794"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="httpBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<serviceCertificate findValue="JRNet01-PC" x509FindType="FindBySubjectName" storeLocation="LocalMachine"
storeName="My" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WcfService自定义授权.MyCustomUserNameValidator,WcfService自定义授权"/>
<clientCertificate>
<!--自定义对客户端进行证书认证方式 这里为 None-->
<authentication certificateValidationMode="Custom"/>
</clientCertificate>
</serviceCredentials>
<serviceAuthorization serviceAuthorizationManagerType="WcfService自定义授权.CustomServiceAuthorizationManager,WcfService自定义授权">
<authorizationPolicies>
<add policyType="WcfService自定义授权.CustomAuthorizationPolicy,WcfService自定义授权"/>
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Web.Config
----------------------------------------------------------------------客户端-------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace WCF自定义授权TestClient
{
class Program
{
static void Main(string[] args)
{
try
{
ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
sc.ClientCredentials.UserName.UserName = "admin";
sc.ClientCredentials.UserName.Password = "";
string result = sc.GetStr("asdfg");
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
}
Program-Main
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="myClientBehavior">
<clientCredentials>
<!--客户端证书-->
<clientCertificate findValue="JRNet01-PC" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://netnetnet-pc:5003/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1" behaviorConfiguration="myClientBehavior">
<identity>
<dns value="JRNet01-PC" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
配置文件
源码下载:WcfService自定义授权.rar
【WCF安全】WCF 自定义授权[用户名+密码+x509证书]的更多相关文章
- WCF安全:通过 扩展实现用户名密码认证
在webSservice时代,可以通过SOAPHEADER的方式很容易将用户名.密码附加到SOAP header消息头上,用户客户端对调用客户端身份的验证.在WCF 时代,也可以通过Operation ...
- WCF加密传输数据,b并且用户名+密码验证
在前2个文章的基础上,继续增加对client 端增加username+password的验证 host增加类Validator,需要添加引用 using System.IdentityModel.Se ...
- Composer 安装时要求输入授权用户名密码?
D:\work\dreamland-yii>composer require "saviorlv/yii2-dysms:dev-master" Authentication ...
- Composer 安装时要求输入授权用户名密码
composer require "overtrue/laravel-socialite:~2.0" Authentication required (packagist.phpc ...
- 解决Composer 使用时要求输入授权用户名密码问题
使用Composer下载第三方包时出现: Authentication required (packagist.phpcomposer.com): Username: 解决方法: 1.修改源 comp ...
- laravel在使用Composer安装插件时要求输入授权用户名密码解决办法
在使用laravel-china源时需要输入密码,坑,换源, 先换腾讯的不行,最后试一下阿里云的可以: composer config -g repo.packagist composer https ...
- WCF之添加自定义用户名密码认证
1.创建WCF服务应用以及调用客户端(请自行google). 2.创建X509证书 cmd 进入 C:\Program Files\Microsoft SDKs\Windows\v6. ...
- 【WCF】使用“用户名/密码”验证的合理方法
我不敢说俺的方法是最佳方案,反正这世界上很多东西都是变动的,正像老子所说的——“反(返)者,道之动”.以往看到有些文章中说,为每个客户端安装证书嫌麻烦,就直接采用把用户名和密码塞在SOAP头中发送,然 ...
- WCF 安全性之 自定义用户名密码验证
案例下载 http://download.csdn.net/detail/woxpp/4113172 客户端调用代码 通过代理类 代理生成 参见 http://www.cnblogs.com/woxp ...
随机推荐
- 20145229吴姗姗web安全基础实践
20145229吴姗姗web安全基础实践 基础与实践 基础问题 (1)SQL注入攻击原理,如何防御 SQL注入就是把SQL语句插入到之前已经定义好的语句中,作为网页中的比如用户名输入来达到攻击的目的, ...
- CentOS 7 源码安装Ansible 2.x
1.安装Python 3.x环境 [root@ansible ~]# yum install -y python36 python36-pip git [root@ansible ~]# ln -s ...
- JavaEE之Junit单元测试
1编写测试类,简单理解Junit可以部分用于取代java的main方法 2在测试类方法上添加注解 @Test 3 @Test修饰的方法要求:public void 方法名() {…} ,方法名自定义建 ...
- Address already in use: make_sock: could not bind to address [::]:80
**********************************************************处理办法:# ps -aux | grep httpWarning: bad syn ...
- java.lang.IllegalArgumentException异常处理的一种方法
我遇到的问题 用spring注解来加载bean,都是一个简单的了,但是还是报了这样一个错java.lang.IllegalArgumentException 网上查了一下,说是jdk版本要1.7的,然 ...
- GroupAnagrams,变形词问题
问题描述:给定一个字符串数组,返回变形词组,变形词是指字母一样但顺序不一样的词. Given an array of strings, group anagrams together. For exa ...
- tech| kafka入门书籍导读
J梳理了一下自己在入门 kafka 时读过的一些书, 希望能帮助到对 kafka 感兴趣的小伙伴. 涉及到的书籍: kafka 权威指南 Kafka: The Definitive Guide (ka ...
- Hash算法-CityHash算法
cityhash系列字符串散列算法是由著名的搜索引擎公司Google 发布的 (http://www.cityhash.org.uk/). Google发布的有两种算法:cityhash64 与 ci ...
- linux命令三
作业一:1) 将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) [root@bogon test]# cat /etc/passwd /etc/group > /1. ...
- LeetCode OJ:Reverse Linked List II(反转链表II)
Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...