最近搞个项目,需要用到WCF来构建服务层,所以考虑到WCF的安全认证了。
WCF的身份认证模式分为
1. 无身份验证: 所有的调用者都能访问服务
2.Windows身份验证:Kerberos(有域服务器)和NTLM(工作组)
3.用户名与密码: 客户端向服务端发送一个用户名和密码,服务端通过一些凭证库来验证
4.X509证书: 客户端包含一个证书,服务端预先知道这些证书,当客户端发送请求时,服务端会验证客户端的证书
5.定制机制: 允许开发者任意使用一种身份验证机制
6.发布口令: 调用者与服务同事依赖一个安全口令
在这里我只描述一下通过MembershipProvider进行用户名/密码的认证
①先建立契约类库Contract具体代码如下
View Code
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.ServiceModel;
5
6
namespace Contracts
7 {
8 [ServiceContract]
9
public
interface IServiceHosting
10 {
11
///
<summary>
12
///
加法
13
///
</summary>
14
///
<param name=”x”></param>
15
///
<param name=”y”></param>
16
///
<returns></returns>
17
[OperationContract]
18
double ADD(
double x,
double y);
19
20
///
<summary>
21
///
减法
22
///
</summary>
23
///
<param name=”x”></param>
24
///
<param name=”y”></param>
25
///
<returns></returns>
26
[OperationContract]
27
double substruction(
double x,
double y);
28
29
///
<summary>
30
///
乘法
31
///
</summary>
32
///
<param name=”x”></param>
33
///
<param name=”y”></param>
34
///
<returns></returns>
35
[OperationContract]
36
double multiplication(
double x,
double y);
37
38
///
<summary>
39
///
除法
40
///
</summary>
41
///
<param name=”x”>
被除数
</param>
42
///
<param name=”y”>
除数
</param>
43
///
<returns></returns>
44
[OperationContract(Name =
“
division
“)]
45
double division(
double x,
double y);
46 }
47 }
第二步 建立 服务类,Service 继承,契约Contract类库里的IServiceHosting接口
View Code
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using Contracts;
5
6
namespace Service
7 {
8
public
class ServiceHosting : IServiceHosting
9 {
10
public
double ADD(
double x,
double y)
11 {
12
return x + y;
13 }
14
15
public
double substruction(
double x,
double y)
16 {
17
return x – y;
18 }
19
20
public
double multiplication(
double x,
double y)
21 {
22
return x * y;
23 }
24
25
public
double division(
double x,
double y)
26 {
27
if (y ==
0)
28 {
29
throw
new Exception(
“
除数不能为零
“);
30 }
31
else
32 {
33
return x / y;
34 }
35 }
36 }
37 }
第三步建立服务主机Hosting控制台程序
View Code
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Web.Security;
5
using System.ServiceModel;
6
using Contracts;
7
using Service;
8
9
namespace Hosting
10 {
11
class Program
12 {
13
static
void Main(
string[] args)
14 {
15
try
16 { //判断数据库里是否有Sytech这个用户,没有就添加一条
17
if (Membership.FindUsersByName(
“
Sytech
“).Count ==
0)
18 {
19 Membership.CreateUser(
“
Sytech
“,
“
ASD!@#123
“,
“
Sytech@sytech.com.cn
“);
20 }
21
using (ServiceHost host =
new ServiceHost(
typeof(ServiceHosting)))
22 {
23 host.Opened +=
delegate
24 {
25 Console.WriteLine(host.BaseAddresses[
0].ToString());
26 };
27 host.Open();
28 Console.WriteLine(
“
Host start
“);
29 Console.Read();
30 }
31 }
32
catch (Exception ex)
33 {
34 Console.WriteLine(ex.Message);
35 Console.Read();
36 }
37 }
38 }
39 }
在这里说明一下啊,这次是通过MembershipProvider来进行密码/用户名的认证,所以需要先生成aspnetdb数据库,这个大家都知道怎么来搞,不知道的可以去baidu查一下。创建出来的数据表可以同时服务于多个应用,所有每一个表中都具有一个名称为ApplicationId的字段来明确该条记录对应的应用。而所有应用记录维护在aspnet_Applications这么一个表中。现在我们需要通过执行下面一段SQL脚本在该表中添加一条表示我们应用的记录
1: INSERT INTO [aspnet_Applications]
2: ([ApplicationName]
3: ,[LoweredApplicationName]
4: ,[ApplicationId]
5: ,[Description])
6: VALUES
7: (
8: ‘Demo’
9: ,’demo’
10: ,NEWID()
11: ,”
12: )
经过这三步,就可以建立服务器端的开发就完成,现在我们来配置服务器端。
服务器端的配置主要是Config的配置,在配置前我们先在服务器上生成服务证书,
制作证书 makecert -r -pe -n “CN=FrankWCFServer” -ss My -sky exchange 通过这个来生成证书(默认是在currentuser,Config里配置就是storeLocation=“CurrentUser“,如果使用makecert -r -pe -n “CN=FrankWCFServer” -ss My -sky exchange -sr LocalMachine,那么证书就存放在本地计算机的个人里 Config里配置就是storeLocation=”LocalMachine”),证书生成后可以在mmc里,添加/或删除管理单元-》证书-添加-》当前用户-》确定,就可以在 个人和受信任的根证书颁发机构 里找到你创建的FrankWCFServer证书。下来配置服务器端的Config。
View Code
“
1.0
“ encoding=
“
utf-8
“ ?>
2 <configuration>
3 <connectionStrings>
4 <add name=
“
aspnetdb
“ connectionString=
“
Server=.; Database=aspnetdb; Uid=sa; Pwd=123456
“/>
5 </connectionStrings>
6 <system.web>
7 <membership defaultProvider=
“
myProvider
“>
8 <providers>//Membership的配置 整个项目使用的.netFramwork3.0
9 <add name=
“
myProvider
“ type=
“
System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
“
10 connectionStringName=
“
aspnetdb
“ applicationName=
“
MembershipAuthenticationDemo
“ requiresQuestionAndAnswer=
“
false
“ />
11 </providers>
12 </membership>
13 </system.web>
14 <system.serviceModel>
15 <services>
16 <service name=
“
Service.ServiceHosting
“ behaviorConfiguration=
“
HostBehaviors
“>
17 <endpoint address=
“” binding=
“
wsHttpBinding
“ bindingConfiguration=
“
userNameCredentialBinding
“ contract=
“
Contracts.IServiceHosting
“ />
18 <host>
19 <baseAddresses>//将Contract和Service 在800端口下发布
20 <add baseAddress=
“
http://win-opvvg1v8458:800/ServiceHosting
“/>
21 </baseAddresses>
22 </host>
23 </service>
24 </services>
25 <behaviors>
26 <serviceBehaviors>
27 <behavior name=
“
HostBehaviors
“>
28 <serviceCredentials>
29 <serviceCertificate storeLocation=
“
CurrentUser
“ storeName=
“
My
“ x509FindType=
“
FindBySubjectName
“ findValue=
“
FrankWCFServer
“/>
30 <userNameAuthentication userNamePasswordValidationMode=
“
MembershipProvider
“ membershipProviderName=
“
myProvider
“/>
31 </serviceCredentials>
32 <serviceMetadata httpGetEnabled=
“
true
“/>
33 </behavior>
34 </serviceBehaviors>
35 </behaviors>
36 <bindings>
37 <wsHttpBinding>
38 <binding name=
“
userNameCredentialBinding
“>
39 <security mode=
“
Message
“>
40 <message clientCredentialType=
“
UserName
“/>
41 </security>
42 </binding>
43 </wsHttpBinding>
44 </bindings>
45 </system.serviceModel>
46 </configuration>
•配置名称为AspNetDb的连接字符串连接的是我们刚刚创建的数据库,并通过aspnet_regsql.exe工具在该数据库中创建了所需的数据库对象;
•表示Membership配置节的<system.web>/<membership>节点下配置了唯一的SqlMembershipProvider,配置名称为myProvider。上面配置的连接字符创名称AspNetDb配置在connectionStringName属性中,意味着该SqlMembershipProvider会将我们创建的数据库作为用户帐号存储;
•服务终结点采用WSHttpBinding,采用Message安全模式,客户端凭证类型被设置为UserName;
•服务应用了一个配置名称为membershipAuthentication的服务行为,该行为中通过<serviceCertificate>节点设置了服务证书。在表示用户名/密码认证配置的<userNameAuthentication>节点中,将认证模式设置成MembershipProvider,而membershipProviderName属性的值为我们在<system.web>/<membership>中设置的MembershipProvider的名称。
到目前为止,在我们创建的数据库中并没有用户帐户记录。为了演示认证的效果,我们必须创建相关用户帐户记录。为了省事,我直接将相关的代码写在了服务寄宿的代码中。如下面的代码片断所示,在对服务进行寄宿之前,我通过调用Membership的静态方法CreateUser创建了一个用户名、密码和Email分别为“Sytech“, “ASD!@#123“, Sytech@sytech.com.cn。这就是我们为什么在Hosting里开始就写
if (Membership.FindUsersByName(“Sytech”).Count == 0)
{
Membership.CreateUser(“Sytech”, “ASD!@#123“, “Sytech@sytech.com.cn“);
}
现在服务器端就可以告一段落。我们来启动Hosting之后可以在浏览器里输入http://win-opvvg1v8458:800/ServiceHosting可以看到如下的页面。
服务器端配置成功。
客户端的调用,在这里建一个控制台应用程序Client,添加服务引用,在地址里输入http://win-opvvg1v8458:800/ServiceHosting点击确定。引用成功Client的Config文件自动配置完成。
然后可以调用了。具体代码如下
View Code
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.ServiceModel.Security;
5
using System.ServiceModel;
6
using Contracts;
7
8
namespace Client
9 {
10
class Program
11 {
12
static
void Main(
string[] args)
13 {
14 Ssss.ServiceHostingClient client =
new Ssss.ServiceHostingClient();
15 UserNamePasswordClientCredential uncc = client.ClientCredentials.UserName;
16 uncc.UserName =
“
Sytech
“;
17 uncc.Password =
“
ASD!@#123
“;
18 Console.WriteLine(client.ADD(
10,
3).ToString());
19 Console.Read();
20 }
21 }
22 }
客户端代码完成,客户端config是在添加引用服务的时候自动添加成功的。不需要配置的。
现在可以运行,客户端程序看看有什么异常!不错,出现异常。这是因为客户端没有导入 服务器端生成的证书。
在服务器端创建的FrankWCFServer这证书,需要导出来FrankWCFServer.cer,将导出来证书,安装在客户端PC上分别安装在当前用户的个人和受信任的根证书颁发机构里,然后在运行客户端程序一看OK了。
在此声明一下,我是一个WCF的初学者,这次的配置是在服务器和客户端两台机器上做的配置,搞了2天,刚才调通,好多东西都不懂,还在学习中,这只是一个笔记,懒得记在本子上,希望看到的别拍砖就行,先行谢过。
转载于:https://www.cnblogs.com/Employee/archive/2011/12/08/2281242.html
今天的文章WCF(安全认证)通过MembershipProvider进行用户名/密码的认证分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/12500.html