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证书]的更多相关文章

  1. WCF安全:通过 扩展实现用户名密码认证

    在webSservice时代,可以通过SOAPHEADER的方式很容易将用户名.密码附加到SOAP header消息头上,用户客户端对调用客户端身份的验证.在WCF 时代,也可以通过Operation ...

  2. WCF加密传输数据,b并且用户名+密码验证

    在前2个文章的基础上,继续增加对client 端增加username+password的验证 host增加类Validator,需要添加引用 using System.IdentityModel.Se ...

  3. Composer 安装时要求输入授权用户名密码?

    D:\work\dreamland-yii>composer require "saviorlv/yii2-dysms:dev-master" Authentication ...

  4. Composer 安装时要求输入授权用户名密码

    composer require "overtrue/laravel-socialite:~2.0" Authentication required (packagist.phpc ...

  5. 解决Composer 使用时要求输入授权用户名密码问题

    使用Composer下载第三方包时出现: Authentication required (packagist.phpcomposer.com): Username: 解决方法: 1.修改源 comp ...

  6. laravel在使用Composer安装插件时要求输入授权用户名密码解决办法

    在使用laravel-china源时需要输入密码,坑,换源, 先换腾讯的不行,最后试一下阿里云的可以: composer config -g repo.packagist composer https ...

  7. WCF之添加自定义用户名密码认证

    1.创建WCF服务应用以及调用客户端(请自行google).  2.创建X509证书       cmd 进入  C:\Program Files\Microsoft SDKs\Windows\v6. ...

  8. 【WCF】使用“用户名/密码”验证的合理方法

    我不敢说俺的方法是最佳方案,反正这世界上很多东西都是变动的,正像老子所说的——“反(返)者,道之动”.以往看到有些文章中说,为每个客户端安装证书嫌麻烦,就直接采用把用户名和密码塞在SOAP头中发送,然 ...

  9. WCF 安全性之 自定义用户名密码验证

    案例下载 http://download.csdn.net/detail/woxpp/4113172 客户端调用代码 通过代理类 代理生成 参见 http://www.cnblogs.com/woxp ...

随机推荐

  1. git报错--RPC failed; curl 18 transfer closed with outstanding read data remaining

    遇到的问题一: error: RPC failed; curl 18 transfer closed with outstanding read data remaining         fata ...

  2. SpringBoot服务器压测对比(jetty、tomcat、undertow)

    1.本次对比基础环境信息如下: springboot版本1.5.10 centos虚机4c6G,版本7.4 centos实机2u16c40G,版本7.4,虚机运行在实机上 ab版本2.3 jprofi ...

  3. 20145201 《Java程序设计》第四周学习总结

    20145201 <Java程序设计>第四周学习总结 教材学习内容总结 本周学习了课本第六.七章内容,即继承与多态.接口与多态. 第六章 继承与多态 6.1 何谓继承 6.1.1 继承共同 ...

  4. java中泛型的一个小问题

    最近做项目,由于java语法不是非常的熟悉,编写代码过程中不难遇到一些问题: 代码里写了一条这种语句: Map<String, List<String>> configFile ...

  5. 使用mysqldump迁移数据

    1. 先停止业务,使用MySQLdump的数据导出工具,将您线下原有数据库数据导出为数据文件 mysqldump -hlocalhost -uroot --default-character-set= ...

  6. lucene学习-2 - 一个示例

    接下来我会写一个lucene的实例.实际上在搜索引擎上随便搜索下都能找到这样的东西.不过还是写一下吧,这也是我学习的经历. package com.zhyea.doggie; import java. ...

  7. RadioButton实现多选一

    RadioButton实现多选一 一.简介 二.RadioButton实现多选一方法 1.将多个RadioButton放在一个RadioGroup里面 <RadioGroup android:i ...

  8. 一个较好的style与ControlTemplate结合的示例(以Button为例)

    <!--按钮背景画刷-->    <LinearGradientBrush x:Key="buttonBackgroundBrush">        &l ...

  9. ConEmu

    https://conemu.github.io/ https://github.com/Maximus5/ConEmu/releases 将控制台整合到一起的工具,支持cmd.powershell. ...

  10. B树, B-树,B+树,和B*树的区别

    B树: B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中: 否则,如果查询关键字比结点关键字小,就进入左儿子:如果比结点关键字大,就进入 右儿子:如果左儿子或右儿子的指针为空, ...