如何使用HTTPS与WCF SessionMode.Required
该解决方案目前使用会话(在ITestServicecs):
[的ServiceContract(SessionMode = SessionModeRequired)]
和使用的wsHttpBinding(见下面的appconfig和网络。 。配置)
当我部署此到服务器时,我能够成功使用HTTPS像这样通过网络浏览器来访问它:的 https://myservercom/test/testservicesvc
不过当我在客户端的appconfig更改端点的:
的http://本地主机:20616 / TestServicesvc / TestServicesvc
到
https://myservercom/test/testservicesvc
并再次运行控制台应用程序,我收到错误:“提供的URI方案的”https“是无效的;预计“HTTP”。参数名:通过“
我的问题是,什么是我需要做这个工作的最小的变化,在不改变SessionModeRequired
下面是客户端的控制台应用程序代码,请务必改变在appconfig值“mycomputer\Matt”,以正确的价值为您的机器。
的Programcs
使用系统;
命名TestClient的
{
类节目
{
静态无效的主要(字串[] args)
{
控制台Clear();
ConsoleWriteLine(“尝试登录”);
试
{
TestServiceReferenceTestServiceClient客户端=新TestServiceReferenceTestServiceClient();
布尔loginSuccess = clientLogIn(“管理员”,“密码”);
如果(loginSuccess)
{
ConsoleWriteLine(“成功登录。 “);
串secretMessage = clientGetSecretData();
ConsoleWriteLine(“检索秘密信息:”+ secretMessage);
}
,否则
{
ConsoleWriteLine(“登录失败!”);
}
}
赶上(例外EXC)
{
ConsoleWriteLine(“异常:”+ excMessage);
}
ConsoleWriteLine(“按ENTER键退出。”);
到ConsoleReadLine();
}
}
}
的Appconfig :
< XML版本=“10”编码=“UTF-8”>?
<结构>
<&启动GT;
< supportedRuntime版本=“V40”SKU =“net框架,版本= V451”/>
< /启动>
< systemserviceModel>
<&绑定GT;
<&的wsHttpBinding GT;
<绑定名称=“WSHttpBinding_ITestService”/>
< /&的wsHttpBinding GT;
< /绑定>
<客户端>
<端点地址=“https://myservercom/test/testservicesvc”绑定=“的wsHttpBinding”bindingConfiguration =“WSHttpBinding_ITestService”合同=“TestServiceReferenceITestService”NAME =“WSHttpBinding_ITestService”>
<同一性GT;
<的UserPrincipalName值=“mycomputer\Matt”/>
< /身份>
< /端点> !
< - <端点地址=“HTTP://本地主机:20616 / TestServicesvc / TestServicesvc”绑定=“的wsHttpBinding”bindingConfiguration =“WSHttpBinding_ITestService”合同=“TestServiceReferenceITestService”NAME = “WSHttpBinding_ITestService”>
<同一性GT;
<的UserPrincipalName值=“mycomputer\Matt”/>
< /身份>
< /端点> - >
< /客户>
< /systemserviceModel>
< /结构>
WCF服务代码结果
ITestServicecs:
使用SystemServiceModel;
命名空间WcfSessionsOverHttpsTest
{
[的ServiceContract(SessionMode = SessionModeRequired)]
公共接口ITestService
{
[ OperationContract的(IsInitiating =真)]
布尔登录(用户名字符串,字符串密码);
[OperationContract的(IsInitiating =假,IsTerminating = TRUE)]
布尔注销();
[OperationContract的(IsInitiating = FALSE)]
串GetSecretData();
}
}
TestServicesvc:
命名空间WcfSessionsOverHttpsTest
{
公共类TestService的:ITestService
{
公布尔IsAuthenticated {搞定;组; }
布尔ITestServiceLogIn(用户名字符串,字符串密码)
{
如果(用户名==“管理员”&放大器;&放大器;密码==“密码”)
$ { b $ b IsAuthenticated = TRUE;
返回真;
}
,否则
{
IsAuthenticated = FALSE;
返回FALSE;
}
}
布尔ITestServiceLogOut()
{
IsAuthenticated = FALSE;
返回真;
}
串ITestServiceGetSecretData()
{
如果(!IsAuthenticated)
{
抛出新SystemSecurityAuthentication。的AuthenticationException(“用户还没有登录。”);
}
,否则
{
串secretMessage =“红袜会赢得世界系列在2016年”;
返回secretMessage;
}
}
}
}
的Webconfig:
< XML版本=“10”>?
<结构>
<&的appSettings GT;
<添加键=“ASPNET:UseTaskFriendlySynchronizationContext”VALUE =“真”/>
< /的appSettings>
<&的SystemWeb GT;
<编译调试=“真”targetFramework =“451”/>
<的httpRuntime targetFramework =“45”/>
< /systemweb>
< systemserviceModel>
<&绑定GT;
<&的wsHttpBinding GT;
<绑定名称=“wsHttpEndpointBinding”closeTimeout =“00:10:00”openTimeout =“00:10:00”receiveTimeout =“00:10:00”的SendTimeout =“00:10:00”maxReceivedMessageSize = “2147483647”>
< readerQuotas MAXDEPTH =“2147483647”maxStringContentLength =“2147483647”maxArrayLength =“2147483647”maxBytesPerRead =“2147483647”maxNameTableCharCount =“2147483647”/>
< /&结合GT;
< /&的wsHttpBinding GT;
< /绑定>
<服务和GT;
<服务名称=“WcfSessionsOverHttpsTestTestService”>
<端点地址=“/ TestServicesvc”绑定=“的wsHttpBinding”bindingConfiguration =“wsHttpEndpointBinding”合同=“WcfSessionsOverHttpsTestITestService”/>
< /服务>
< /服务>
<&行为GT;
< serviceBehaviors>
<&行为GT;
< serviceMetadata httpGetEnabled =“真”httpsGetEnabled =“真”/>
< serviceDebug includeExceptionDetailInFaults =“FALSE”/>
< /行为>
< / serviceBehaviors>
< /行为>
< protocolMapping>
<添加绑定=“的wsHttpBinding”计划=“HTTP”/>
< / protocolMapping>
< serviceHostingEnvironment aspNetCompatibilityEnabled =“真”multipleSiteBindingsEnabled =“真”/>
< /systemserviceModel>
< systemwebServer>
<模块runAllManagedModulesForAllRequests =“真”/>
<启用directoryBrowse =“真”/>
< /systemwebServer>
< /结构>
在此先感谢您的帮助!
太
解决方案
解决这个问题是我需要补充的是,从派生的类“UserNamePasswordValidator”并注册它的WebConfig
公共类CustomUserNameValidator:UserNamePasswordValidator
{
公覆盖void验证(用户名字符串,字符串密码)
{
的回报;
}
}
Webconfig文件:
<&行为GT;
< serviceBehaviors>
<&行为GT;
<! - 为了避免泄露的元数据信息,在部署之前设置以下为false值 - >
< serviceMetadata httpsGetEnabled =“真”/>
<! - 要接收的异常细节的故障进行调试,下面设置为true值。设置为false部署之前,以避免泄露异常信息 - >
< serviceDebug includeExceptionDetailInFaults =“真”/>
< serviceCredentials>
< userNameAuthentication userNamePasswordValidationMode =“自定义”customUserNamePasswordValidatorType =“MyProgramCustomUserNameValidator,MyProgram”/>
< / serviceCredentials>
< /行为>
< / serviceBehaviors>
< /行为>
主要的原因在于重新部署和访问权限的问题。
如果你修改了DLL内容,那么你必须要将修改DLL发送到客户端,如果你的DLL改了文件名,你的客户端必须要更新所有调用它文件;而是用WCF就没有这样的问题,你只需要更新WCF就可以,
而将DLL直接部署到客户端,且这个DLL是和有访问限制的内容打交道的。即便你在DLL中设置的访问权限什么的。但你要知道,在客户机上运行的程序都是在客户机内存的,破解本地的数据要比黑掉服务器来的简单的多;并且,如果将DLL部署在客户端,那么就相当于所有的客户机都是直接于数据服务器相连的,为黑掉服务器打开了方便之门。
说白了,就和网络游戏的客户端和服务器一样的道理。为什么网游的客户端不直接连数据库处理,非得花大价钱用服务器,所谓的分布式计算不是很好么。道理就是这样的,一个是安全,一个方便更新和控制
WCF在跨域传输使用了两种模型的方法调用:一种是同步模型,这种模型显然对那些需要大量操作时间的方法调用(如从数据库中获取大量数据时)是一种痛苦的选择。另一种是异步模型的方法调用,这种模型是一种非阻塞方法,其方法调用期间并不等到方法调用结束获得结果才返回,而是方法调用一经开始就马上返回,程序可以继续向前执行,被调用方法和主程序同时执行,在调用方法结束才返回结果。显然这种模型给了我们很好的编程和使用体验。
基于WCF在普通的编码是以文本编码方式在信道之间传输信息的,这种编码会把所有的二进制信息以字节数组的形式存储,并以Base64进行编码,而Base64则是用三个字节来储存4 个字符信息。使得数据量增大约30%以上。在WCF中引入了一种专门针对数据流进行优化编码的MTOM模型。下面我们使用编码模型和调用模型三种方式来改写文件流的传输,以提高WCF应用程序的性能。
1、 MTOM模型:
这模型在于将SOAP消息编码成SOAP MT OM(消息传输优化机制)编码。这种编码是为那些包含大量的二进制数据的SOAP消息而做的,它是把数据流作为SOAP消息的附件而添加的。所以利用这种编码在传输信道之间传输可以显著提高传输性能。在WCF中MTOM模型的操作契约中只能使用单个Stream对象作为参数或者返回类型。
这种模型的特点如图所示:
11实现服务契约
服务契约是服务所支持的操作、使用的消息交换模式和每一则消息的格式,它控制消息被格式化的方式,在这里由于要使用MTOM编码消息,所以在操作契约中必须要以单一的Stream对象为输入输出参数。所以这儿我们把服务定义为如下的形式:
[ServiceContract]
public interface ISendStreamService
{
[OperationContract]
void SendStream(Stream stream);
//这个方法的是为了传递文件的参数而设的
[OperationContract]
void FileNameSetting(string filename, string destinationpath);
}
另外我们还定义了一个传输文件路径的名称的辅助方法:FileNameSetting();
12实现服务器方法
在上面定义了公共的接口后,接下来我们就实现接口的方法,主要的方法的目的是为了传输Stream对象,由于Stream是一个抽象类,所以这儿以文件流为操作对象来使用SendStream()这个方法。
13客户通过接口调用服务器方法
客户端调用服务器方法至少有三种,这里我们选择工厂方法来实现,SystemServiceModeChannelChannelFactory<T>类是这个信道工厂类,它的方法CreateChannel()可以创建T的实例。
ISendStreamService proxy=new
ChannelFactory<ISendStreamService>(“WSHttpBinding_ISendStreamService”)Create-
Channel();
proxyFileNameSetting(fileSubstring (fileLastIndexOf ("\\")+1), filePath);
proxySendStream(inStream);
14服务器和客户端的配置信息
配置信息定义了双方通信的终结点、绑定、契约行为及其他的配置如安全,可靠性等。服务器的配置如:
<service behaviorConfiguration="SendStreamServiceBehavior"
name="SendStreamService">
<endpoint address=" http://localhost:5504/WebSite2/ISendStreamService "
binding="wsHttpBinding" bindingConfiguration="MTMOBinding"
contract="ISendStreamService">
</endpoint>
<bindings>
<wsHttpBinding>
<binding name="MTMOBinding" messageEncoding="Mtom">
</wsHttpBinding>
</bindings>
</service>
0条评论