WCF安全,用户名密码无证书

发布于 2024-11-18 11:07:02 字数 3208 浏览 1 评论 0原文

我是 WCF 的新手。我习惯了 *.asmx,但它将被弃用,因此我决定深入研究 WCF。我想要为我的服务进行简单的用户名+密码身份验证,但网络上的任何地方都与 X509 证书有关。我想在 IIS 中托管我的服务,因此我将在那里启用 SSL

我已经遵循了一些关于 WCF 的 hello world 教程,但对所有新事物、数据契约、OperationContract、ServiceContract、所需接口、web.config 中的所有绑定、basicHttpBinding 等有点困惑。

我目前在 文件 ->新项目->视觉 C# -> WCF-> WCF 服务应用程序

我有一种 hello world 应用程序,想知道保护它的最佳和最简单的方法是什么。我读过很多不同的东西,以至于我不知道什么最适合我的情况。

IIS 中托管的服务将在 Internet 上提供(启用 ssl),并且我想将用户名和密码发送给几个值得信赖的人。

请建议我最简单且合适的安全性。

编辑 我正在尝试关注这篇博文: http://codebetter.com/petervanooijen/2010/03/22/a-simple-wcf-service-with-username-password-authentication-the-things-they-don-t-tell-you/< /a> 但我在发布元数据时遇到了麻烦。 中有错误

<system.serviceModel>
    <services>
        <service behaviorConfiguration="WcfServiceSimStars.MyServiceTypeBehaviors" name="FarmService.CustomerDeskOperations">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="RequestUserName" contract="WcfServiceSimStars.ISimService" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
        </service>
    </services>
    <bindings>
        <wsHttpBinding>
            <binding name="RequestUserName" >
                <security mode="Message">
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://mytestserver/simservice.svc" binding="WSHttpBinding"
            bindingConfiguration="WSHttpBinding_ISimService" contract="WcfServiceSimStars.ISimService"
            name="WSHttpBinding_ISimService" />
    </client>
    <behaviors>
        <serviceBehaviors>
            <behavior name="WcfServiceSimStars.MyServiceTypeBehaviors">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceSimStars.UserValidatorr, WcfServiceSimStars" />
                    <serviceCertificate findValue="Farm" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

我假设我的 web.config和解决方案资源管理器

solution explorer

编辑2: 我尝试使用 Visual Studio 工具菜单中的 Microsoft 服务配置编辑器 打开 web.config 并收到此错误:

Microsoft 服务配置编辑器

I am new to WCF. I was used to *.asmx but it will become deprecated, so I decided to dive into WCF. I want a simple username + password authentication for my service, but everywhere on the web it's all about X509 certificates. I'd like to host my service in IIS, so I will enable SSL there.

I have followed some hello world tutorials on WCF but am a bit confused with all the new things, datacontract, OperationContract, ServiceContract, required interfaces, all the bindings in web.config, basicHttpBinding etc.

I am currently at File -> New project -> Visual C# -> WCF -> WCF Service Application

I have a kind of hello world app, and would like to know what the best and easiest way is to secure it. I have read so much different things that I just don't have a clue what is the best for my situation.

The service hosted in IIS will be available on the internet (with ssl enabled) and the usernames and passwords i'd like to send out to several trusted people.

Please advice me for the easiest and suitable security.

Edit
I am trying to follow this blogpost:
http://codebetter.com/petervanooijen/2010/03/22/a-simple-wcf-service-with-username-password-authentication-the-things-they-don-t-tell-you/
but I have trouble with publishing the metadata. I assume that there is an error in my web.config

<system.serviceModel>
    <services>
        <service behaviorConfiguration="WcfServiceSimStars.MyServiceTypeBehaviors" name="FarmService.CustomerDeskOperations">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="RequestUserName" contract="WcfServiceSimStars.ISimService" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
        </service>
    </services>
    <bindings>
        <wsHttpBinding>
            <binding name="RequestUserName" >
                <security mode="Message">
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://mytestserver/simservice.svc" binding="WSHttpBinding"
            bindingConfiguration="WSHttpBinding_ISimService" contract="WcfServiceSimStars.ISimService"
            name="WSHttpBinding_ISimService" />
    </client>
    <behaviors>
        <serviceBehaviors>
            <behavior name="WcfServiceSimStars.MyServiceTypeBehaviors">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceSimStars.UserValidatorr, WcfServiceSimStars" />
                    <serviceCertificate findValue="Farm" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

and my solution explorer:

solution explorer

Edit 2:
I tried to open my web.config with the Microsoft Service Configuration Editor from visual studio tools menu and got this error:

Microsoft Service Configuration Editor

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情深已缘浅 2024-11-25 11:07:02

如果您想使用 SSL,则需要使用 X509 证书。

如果要将其托管在 IIS 上并启用 SSL,则需要提供证书,出于调试目的,您可以从 IIS 中生成自签名证书。

在 IIS 中设置完毕后,您将需要编辑 WCF 绑定以启用 SSL。

您将需要与安全模式传输集和安全行为的绑定

<basicHttpBinding>
    <binding name="SecureBinding" receiveTimeout="01:00:00">
      <security mode="Transport" />
    </binding>
</basicHttpBinding>

,以下指定将使用的 ssl 证书。

<behaviors>
  <serviceBehaviors>
    <behavior name="SecureBehavior">
      <serviceMetadata />
      <serviceCredentials>
        <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
      </serviceCredentials>
    </behavior>
    <behavior name="StandardBehavior">
    </behavior>
  </serviceBehaviors>
</behaviors>

然后您需要创建一个安全端点

<services>
  <service behaviorConfiguration="SecureBehavior" name="secureService">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="SecureBinding" contract="<Your webservice class name including namespace>" />
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
  </service>

一旦托管,您就可以在网站上使用 SSL。

要从客户端连接,您将使用以下命令(假设是 C#)。

BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Transport;
EndPointAddress endpointAddress = new EndpointAddress("Your Service address (including HTTPS)");
Client svc = new Client(binding,endpointAddress)

另一种方法是使用加密而不是 SSL。在客户端加密密码并将加密数据发送到服务,但我不太确定这样做的最佳实践。

希望这有助于

编辑

如果您想将用户名和密码发送到服务,您只需要在服务中创建一个新方法。

您将在接口文件 (IService1.cs) 中定义操作协定,

[OperationContract]
bool Login(string password,string username);

然后在服务类 (Service1.svc) 中创建方法,

public bool Login(string password,string username)
{
    //Your Code to check the username and password here
}

这可能是最简单的方法。另一种更复杂的方法是使用自定义会员资格提供程序来验证用户身份。

您需要创建一个继承自 MembershipProvider 的类并覆盖 ValidateUser 方法

public class SampleMembershipProvider : MembershipProvider
{ 
    public override bool ValidateUser(string username, string password)
    {
        //check the username and password here
    }


    //No need to override the other methods just leave them
    ....
}

,现在您需要告诉 webconfig 使用表单身份验证并使用您的自定义会员资格提供程序

<authentication mode="Forms" />
<membership defaultProvider="CustomMembershipProvider">
  <providers>
    <clear />
    <add name="CustomMembershipProvider" type="SampleApplication.CustomMembershipProvider" />
  </providers>
</membership>

现在您已经设置了会员资格提供程序,您可以从以下位置更改您的登录代码将上面的代码添加到以下代码中,此代码将对用户进行身份验证并设置授权 cookie。

public bool Login(string password,string username)
{
    if (Membership.ValidateUser(username, password))
    {
        FormsAuthentication.SetAuthCookie(username, false);
        return true;
    }
    return false;
}

现在,当您在服务上调用方法时,您可以检查用户是否经过身份验证,如果是,您可以运行该命令,否则不要运行。

bool DoWork()
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
         //do something
         return true;
    }
    else
    {
        return false;
    }
}

如果您需要我澄清任何事情,请告诉我

If you want to use SSL you will need to use X509 certificates.

If you are going to host it on IIS and enable SSL there you will need to provide a certificate, for debug purposes you can generate a self signed certificate from within IIS.

Once you have set it up within IIS you will need to edit the WCF Binding to enable SSL.

You will need a binding with security mode transport set

<basicHttpBinding>
    <binding name="SecureBinding" receiveTimeout="01:00:00">
      <security mode="Transport" />
    </binding>
</basicHttpBinding>

and a secure behaviour, the following specifies the ssl certificate that will be used.

<behaviors>
  <serviceBehaviors>
    <behavior name="SecureBehavior">
      <serviceMetadata />
      <serviceCredentials>
        <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
      </serviceCredentials>
    </behavior>
    <behavior name="StandardBehavior">
    </behavior>
  </serviceBehaviors>
</behaviors>

you then need to create a secure endpoint

<services>
  <service behaviorConfiguration="SecureBehavior" name="secureService">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="SecureBinding" contract="<Your webservice class name including namespace>" />
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
  </service>

That should enable you to used SSL on your site once it is hosted.

To connect from your client you would use the following (assuming C#)

BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Transport;
EndPointAddress endpointAddress = new EndpointAddress("Your Service address (including HTTPS)");
Client svc = new Client(binding,endpointAddress)

The other method would be to use encryption instead of SSL. Encrypt the password on the client side and send the encrypted data to the service, i'm not really sure on the best practices for doing that though.

Hope this helps

EDIT

If you wanted to send a username and password to the service you would just need to create a new method within the service.

You would define an operation contract within the interface file (IService1.cs)

[OperationContract]
bool Login(string password,string username);

then you would create the method within the service class (Service1.svc)

public bool Login(string password,string username)
{
    //Your Code to check the username and password here
}

Thats probably the simplest way to do it. Another more complex way would be to use a custom Membership provider to authenticate users.

You would need to create a class that inherits from MembershipProvider and override the ValidateUser method

public class SampleMembershipProvider : MembershipProvider
{ 
    public override bool ValidateUser(string username, string password)
    {
        //check the username and password here
    }


    //No need to override the other methods just leave them
    ....
}

now you need to tell the webconfig to use forms authentication and to use your custom membership provider

<authentication mode="Forms" />
<membership defaultProvider="CustomMembershipProvider">
  <providers>
    <clear />
    <add name="CustomMembershipProvider" type="SampleApplication.CustomMembershipProvider" />
  </providers>
</membership>

Now that you have your membership provider set up you can change your login code from above to the following code, this code will authenticate the user and sets an authorisation cookie.

public bool Login(string password,string username)
{
    if (Membership.ValidateUser(username, password))
    {
        FormsAuthentication.SetAuthCookie(username, false);
        return true;
    }
    return false;
}

Now when ever you call a method on your service you can check if the user is authenticated and if they are you can run the command otherwise don't.

bool DoWork()
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
         //do something
         return true;
    }
    else
    {
        return false;
    }
}

Let me know if you need me to clarify anything

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文