C#WCF基于会话的服务,具有自定义用户名/密码验证:配置问题

时间:2013-06-11 10:34:15

标签: c# wcf custom-authentication

我在stackoverflow上搜索了很多已发布的答案,但到目前为止,所提出的解决方案都没有解决我的问题。那是研究的第二天。没有结果的故障排除,所以我要求别人帮忙。我正在开发一个WPF数据库应用程序,我想在WPF应用程序和数据库之间添加一个中间层(WCF)。

WCF服务有两个服务合同,都启用了自定义用户名/密码身份验证(也需要会话)。第一个服务合同(IAppUserService)将为本地用户运行的WPF应用程序提供服务,第二个服务合同将为客户可访问的网站提供服务(IAppClientService)。

我已经包含以下源代码:

DCMAppService.svc.cs

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
using System.IdentityModel.Selectors;
using MySql.Data.MySqlClient;
using DCMAppService.classes;

namespace DCMAppService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class AppClientService : IAppClientService
    {
        public bool Login(string userName, string password)
        {
                    // TODO:
            return true;
        }

        public bool Logout()
        {
                    // TODO:
            return true;
        }
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class AppUserService : IAppUserService
    {
        private User currentUser;


        #region User functions
        public User Login(string userName, string password)
        {
                    // Does Login here...
        }

        public bool Logout()
        {
                    // Does logout here...
        }

        public bool isLoggedIn()
        {
            return (currentUser != null);
        }

        public User AddUser(string firstName, string lastName, string userName, string password, ushort status)
        {
                    // Implements business logic...
        }

        public bool UpdateUser(uint id, string firstName, string lastName, string userName, string password, ushort status)
        {
                    // Implements business logic...
        }

        public bool DeleteUser(uint id)
        {
                    // Implements business logic...
        }

        public List<User> GetUsersList()
        {
                    // Implements business logic...
        }
        #endregion

        #region Client functions
        public Client AddClient(string title, bool allowWebAccess, string userName, string password)
        {
                    // Implements business logic...
        }

        public bool UpdateClient(uint id, string title, bool allowWebAccess, string userName, string password)
        {
                    // Implements business logic...
        }

        public bool DeleteClient(uint id)
        {
                    // Implements business logic...
        }

        public List<Client> GetClientsList()
        {
                    // Implements business logic...
        }
        #endregion
    }

    public class CustomUserNameValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName == null || password == null)
                throw new ArgumentNullException();

            // Custom login implementation
                    // TODO:
                    int ret = 1;
            if (ret != 1)
                throw new FaultException("Invalid username or password", new FaultCode("AuthError"));
        }
    }
}

服务的接口文件包含以下内容:

IDCMAppService.cs

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

namespace DCMAppService
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IAppClientService
    {
        [OperationContract(IsInitiating = true, IsTerminating = false)]
        bool Login(string userName, string password);

        [OperationContract(IsInitiating = false, IsTerminating = true)]
        bool Logout();
    }

    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IAppUserService
    {
        [OperationContract]
        bool HealthCheck();

        #region User functions
        [OperationContract(IsInitiating = true, IsTerminating = false)]
        User Login(string userName, string password);

        [OperationContract(IsInitiating = false, IsTerminating = true)]
        bool Logout();

        [OperationContract(IsInitiating = false)]
        User AddUser(string firstName, string lastName, string userName, string password, ushort status);

        [OperationContract(IsInitiating = false)]
        bool UpdateUser(uint id, string firstName, string lastName, string userName, string password, ushort status);

        [OperationContract(IsInitiating = false)]
        bool DeleteUser(uint id);

        [OperationContract(IsInitiating = false)]
        List<User> GetUsersList();
        #endregion

        #region Client functions
        [OperationContract(IsInitiating = false)]
        Client AddClient(string title, bool allowWebAccess, string userName, string password);

        [OperationContract(IsInitiating = false)]
        bool UpdateClient(uint id, string title, bool allowWebAccess, string userName, string password);

        [OperationContract(IsInitiating = false)]
        bool DeleteClient(uint id);

        [OperationContract(IsInitiating = false)]
        List<Client> GetClientsList();
        #endregion
    }
}

请注意,包含WCF必须提供的两种不同的服务合同(一种用于用户,另一种用于客户)。

Web.config文件包含以下内容:

<?xml version="1.0"?>
<configuration>
    <appSettings/>
    <connectionStrings>
        <add name="DCMConnectionString" connectionString="Server=127.0.0.1;Database=xxxxxx;Uid=xxxxxx;Pwd=xxxxxx;" providerName="System.Data.EntityClient"/>
    </connectionStrings>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
        </compilation>
        <!--
        The <authentication> section enables configuration 
        of the security authentication mode used by 
        ASP.NET to identify an incoming user. 
    -->
        <authentication mode="Windows"/>
        <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
         <error statusCode="403" redirect="NoAccess.htm" />
         <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
      -->
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
    </system.web>
    <system.serviceModel>
        <protocolMapping>
            <remove scheme="http" />
            <add scheme="http" binding="wsHttpBinding" />
        </protocolMapping>
        <bindings>
            <wsHttpBinding>
                <binding name="DCMAppBindingWSConfig" receiveTimeout="03:00:00"
                 sendTimeout="03:00:00">
                    <reliableSession inactivityTimeout="01:00:00" enabled="true" />
                    <security mode="Message">
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
            </wsHttpBinding>
            <mexHttpBinding>
                <binding name="DCMAppBindingMexConfig" receiveTimeout="00:10:00"
                 sendTimeout="00:10:00" />
            </mexHttpBinding>
        </bindings>
        <services>
            <service behaviorConfiguration="DCMAppService.AppServiceBehavior"
             name="DCMAppService.AppUserService">
                <endpoint address="" binding="wsHttpBinding" name="wsBinding"
                 contract="DCMAppService.IAppUserService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="DCMAppBindingMexConfig"
                 name="mexBinding" contract="IMetadataExchange" />
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="DCMAppService.AppServiceBehavior">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                    <serviceCredentials>
                        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="DCMAppService.CustomUserNameValidator, DCMAppService" />
                    </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

我得到的回复是带有经典消息的错误页面:

此服务的元数据发布目前已停用。

这很烦人,因为我找不到任何方法来解决它。

非常感谢任何帮助。

0 个答案:

没有答案