您的位置:首页 > 其它

WCF安全操练(2)--WCF服务端

2009-08-31 13:40 113 查看
说明:要建立的WCF服务的安全验证方式为TransportWithMessageCredential,这意味着建立客户端调用WCF服务时,即要信任服务器端的证书,又要提供用户名和密码。好处第一是安全,第二是可以对服务中的任何方法实现权限控制。

在.NET 2008中新建项目,项目模板选WCF服务应用程序。

在项目中添加对System.IdentityModel的引用。

在项目中添加一个新类,该类可以做用户的简单认证或是保存调用服务者的信息,我主要将该类用于后者。类代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace WcfServiceForMyself
{
    public class UserValidator : UserNamePasswordValidator
    {
        string customUserName;
        string custompassword;

        public override void Validate(string userName, string password)
        {
            

            if (string.IsNullOrEmpty(userName))
                throw new ArgumentNullException("userName");
            if (string.IsNullOrEmpty(password))
                throw new ArgumentNullException("password");
            //这里可加简单的用户判断,如
            //if (userName != "Admin" || password != "123")
            //    throw new SecurityTokenException("用户名或者密码错误!");

            customUserName = userName;
            custompassword = password;
        }

        public string CustomUserName
        {
            get
            {
                return customUserName;
            }
        }

        public string CustomPassWord
        {
            get
            {
                return custompassword;
            }
        }
    }
}


服务的接口如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceForMyself
{
    // NOTE: If you change the interface name "IServiceForMyself" here, you must also update the reference to "IServiceForMyself" in Web.config.
    [ServiceContract]
    public interface IServiceForMyself
    {
        [OperationContract]
        string PrintMessage(string message);
    }
}


服务实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace WcfServiceForMyself
{
    // NOTE: If you change the class name "ServiceForMyself" here, you must also update the reference to "ServiceForMyself" in Web.config.
    public class ServiceForMyself : IServiceForMyself
    {
        //
        WcfServiceForMyself.UserValidator myClientUser;

        public ServiceForMyself()
        {
            myClientUser = (WcfServiceForMyself.UserValidator)OperationContext.Current.Host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator;
        }

        public WcfServiceForMyself.UserValidator MyClientUser
        {
            get
            {
                return myClientUser;
            }
        }

        public string PrintMessage(string msg)
        {
            //此时可根据客户端的用户来判断用户是否有权调用接口,如
            if (myClientUser.CustomUserName == "Admin")
            {
                msg = "输出信息(" + msg + ")";
                return msg;
            }
            else
            {
                return "你没有调用此接口的权限";
            }
        }
    }
}


注意以下Web.Config中的<system.serviceModel>中的配置,如下:

<system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="WcfServiceForMyself.ServiceForMyselfBehavior">
                    <serviceMetadata httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                  <serviceCredentials>
                    <issuedTokenAuthentication allowUntrustedRsaIssuers="true"></issuedTokenAuthentication>
                    <clientCertificate>
                      <authentication certificateValidationMode="None"/>
                    </clientCertificate>
                    <serviceCertificate findValue="10.11.41.87" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My"/>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceForMyself.UserValidator,WcfServiceForMyself"/>
                  </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="WcfServiceForMyself.ServiceForMyselfBehavior"
                name="WcfServiceForMyself.ServiceForMyself">
                <endpoint address="" binding="basicHttpBinding" contract="WcfServiceForMyself.IServiceForMyself" bindingConfiguration="myUserSafeBinding">
                    <identity>
                        <dns value="10.11.41.87" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
            </service>
        </services>
      <bindings>
        <basicHttpBinding>
          <binding name="myUserSafeBinding">
            <security mode="TransportWithMessageCredential">
              <transport clientCredentialType="Windows"/>
              <message clientCredentialType="UserName"/>
            </security>
          </binding>
        </basicHttpBinding>
      </bindings>
    </system.serviceModel>


我建立的这个WCF服务是想要在silverlight3中应用的,所以用的是basicHttpBinding方式。

好了,服务完成了,发布到IIS中,发布后将该服务按下图配置:



在安全通信中点击编辑,选择如下:



确定后完成配置,OK,服务端的程序完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: