[WCF安全1]使用basicHttpBinding构建UserName授权的WCF应用程序
最近到了新公司,leader让我研究一下WCF的传输安全机制。以前也做过WCF的应用,但是很少涉及安全方面的东西。所以,花了三天的时间研究了一下如何在WCF的应用程序中配置安全。在这个系列文章中,我会将我的一些心得分享给大家,希望对大家有所帮助。
我所做的研究主要是使用UserName的验证方式,对请求进行验证,本文主要介绍使用basicHttpBinding进行验证,后续两篇文章中将针对wsHttpBinding介绍使用http方式验证以及https(SSL)方式验证。
首先,想跟大家说明,这几篇帖子,我的重点在于如何配置WCF应用程序,使你的WCF程序能够使用UserName的安全验证;而不在于如何建立WCF应用程序,如果大家想了解关于建立WCF应用程序的相关知识,请参考MSDN相关文档。
Let's go!
我将我的应用程序分为服务端与访问端,下面让我们分别看服务端与客户端。
1. 服务端
(1) 创建CustomUserNameValidator
CustomUserNameValidator从UserNamePasswordValidator类继承,并且需要实现抽象方法Validate,可以在其中实现用户名密码验证逻辑,如果验证不成功,抛出异常。
public class CustomUserNameValidator : UserNamePasswordValidator
{
private const string USERNAME_ELEMENT_NAME = "userName"; private const string PASSWORD_ELEMENT_NAME = "password"; private const string FAULT_EXCEPTION_MESSAGE = "UserName or Password is incorrect!"; public override void Validate(string userName, string password)
{
Guarder.Guard.ArgumentNotNull(userName)
.ArgumentNotNull(password);
var validateUserName = ConfigurationManager.AppSettings[USERNAME_ELEMENT_NAME];
var validatePassword = ConfigurationManager.AppSettings[PASSWORD_ELEMENT_NAME];
var validateCondition = userName.Equals(validateUserName) && password.Equals(validatePassword);
if (!validateCondition)
{
throw new FaultException(FAULT_EXCEPTION_MESSAGE);
}
}
}
(2) 完成服务端配置文件
服务端配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="customBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="EmployeesHost.CustomUserNameValidator, EmployeesHost"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings >
<basicHttpBinding>
<binding name="EmployeeQueryBinding_BasicHttp">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="EmployeesHost.EmployeesQueryService" behaviorConfiguration="customBehavior">
<!--For basic http binding endpoint-->
<endpoint address="http://127.0.0.1:12215/EmployeeQuery" binding="basicHttpBinding"
bindingConfiguration="EmployeeQueryBinding_BasicHttp"
contract="EmployeesHost.IEmployeesQueryService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8733/Design_Time_Addresses/EmployeesHost/EmployeesQueryService/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<appSettings>
<add key="userName" value="username"/>
<add key="password" value="password"/>
</appSettings>
</configuration>
需要注意的是,serviceCredentials节点中需要按照上面文件中的写法。binding节点中也需要严格按照上面文件中所写。、
(3) 完成ServiceHost启动
启动ServiceHost代码:
static void Main(string[] args)
{
var host = new ServiceHost(typeof(EmployeesQueryService));
host.Open();
Console.WriteLine("Service Host opened, press <s> to stop...");
var key = Console.ReadKey();
if (key.Key == ConsoleKey.S)
{
host.Close();
}
Console.WriteLine("Press any key to quit...");
Console.ReadKey();
14 }
2. 客户端
(1) 客户端配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="DefaultBinding_IEmployeesQueryService">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<!--For basic http binding endpoint-->
<endpoint address="http://127.0.0.1:12215/EmployeeQuery/"
binding="basicHttpBinding" bindingConfiguration="DefaultBinding_IEmployeesQueryService"
contract="IEmployeesQueryService" name="DefaultBinding_IEmployeesQueryService_IEmployeesQueryService" />
</client>
</system.serviceModel>
<appSettings>
<add key="userName" value="username"/>
<add key="password" value="password"/>
</appSettings>
</configuration>
注意,客户端配置文件中的binding节点,需要与服务端的binding节点写法相同。
(2) 客户端调用代码
var userName = ConfigurationManager.AppSettings[USERNAME_ELEMENT_NAME];
var password = ConfigurationManager.AppSettings[PASSWORD_ELEMENT_NAME];
mProxy.ClientCredentials.UserName.UserName = userName;
mProxy.ClientCredentials.UserName.Password = password;
var data = mProxy.GetData();
OK,大功告成,运行,ok。
下一篇:[WCF安全2]使用wsHttpBinding构建UserName授权的WCF应用程序,非SSL
[WCF安全1]使用basicHttpBinding构建UserName授权的WCF应用程序的更多相关文章
- [WCF安全2]使用wsHttpBinding构建UserName授权的WCF应用程序,非SSL
上一篇文章中介绍了如何使用basicHttpBinding构建UserName授权的WCF应用程序,本文将为您介绍如何使用wsHttpBinding构建非SSL的UserName安全授权的WCF应用程 ...
- [WCF安全3]使用wsHttpBinding构建基于SSL与UserName授权的WCF应用程序
上一篇文章中介绍了如何使用wsHttpBinding构建UserName授权的WCF应用程序,本文将为您介绍如何使用wsHttpBinding构建基于SSL的UserName安全授权的WCF应用程序. ...
- 构建RESTful风格的WCF服务
构建RESTful风格的WCF服务 RESTful Wcf是一种基于Http协议的服务架构风格. 相较 WCF.WebService 使用 SOAP.WSDL.WS-* 而言,几乎所有的语言和网络平台 ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...
- WCF开发实战系列一:创建第一个WCF服务
WCF开发实战系列一:创建第一个WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在这个实战中我们将使用DataContract,ServiceContract ...
- WCF开发实战系列二:使用IIS发布WCF服务
WCF开发实战系列二:使用IIS发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇中,我们创建了一个简单的WCF服务,在测试的时候,我们使用VS200 ...
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包【转】
引文:我们公司是做自己使用产品,迭代更新周期短,每次都花费较多时间和精力打包做增量更新,发现了一篇文章用于 自动构建svn增量/全量 系统程序升级包,收藏之,希望可以通过学习,更加简化我们的工作. 文 ...
- 知道WCF的地址用工厂通道方式快速调用WCF
知道WCF的地址用工厂通道方式快速调用WCF 1 using System; 2 using System.ServiceModel; 3 using System.ServiceModel.D ...
随机推荐
- 单例Singleton模式的两种实现方法
在设计模式中,有一种叫Singleton模式的,用它可以实现一次只运行一个实例.就是说在程序运行期间,某个类只能有一个实例在运行.这种模式用途比较广泛,会经常用到,下面是Singleton模式的两种实 ...
- js原生函数bind
/*在javascript中,函数总是在一个特殊的上下文执行(称为执行上下文),如果你将一个对象的函数赋值给另外一个变量的话,这个函数的执行上下文就变为这个变量的上下文了.下面的一个例子能很好的说明这 ...
- Wilcoxon符号秩+秩和检验学习[转载]
参数检验就是已知数据的精确分布模型,根据数据来求出模型中的未知参数:而非参数检验就是无需对样本总体分布(比如满足正态分布)做出假设. 1.符号检验 转自:https://baike.baidu.com ...
- Spring基本功能-依赖注入
一.Spring的依赖注入(DI) 1.1 xml形式注入 (1)普通变量的注入 //普通变量的注入,xml配置property,实体类配置set方法注入 <bean id="pers ...
- php now 5.2 升级5.3
简单说明 在WIN上有时候需要测试一些PHP程序,又不会自行独立配置环境,那么PHPNow是非常好的选择. PHPNow自带的PHP版本为5.2.14,而最后一次更新在于2010-9-22,PHP5. ...
- 核心动画(CAKeyframeAnimation,CABasicAnimation)
一,核心动画常用的三种例子 view的核心动画其体现就是把view按照指定好的路径进行运动,针对的是view的整体. [view.layer addAnimation:动画路径 forKey:@“绑定 ...
- 验证APNS证书的有效性
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert xxx.pem
- 十八般武艺之 Runloop
嗯,runloop ,看过,用过.但是有时候突然被问到,总是不能很好的描述给他人,也许是程序员本来口拙的缘故吧.另外,也是对runloop还是理解的不够透彻. 于是乎,决定重新整理一下,加深一下印象. ...
- netty6---序列化与反序列化
package com.cn; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import ja ...
- 多媒体文件格式分析 MP3文件结构及编解码流程
多媒体文件格式分析 http://blog.csdn.net/taniya001/article/details/7962864 多媒体文件格式分析 MP3文件结构及编解码流程 http://www. ...