如何在 WCF 服务上设置密码?

Posted

技术标签:

【中文标题】如何在 WCF 服务上设置密码?【英文标题】:How to put a password on a WCF Service? 【发布时间】:2011-07-08 09:44:26 【问题描述】:

我正在开发由我们的其他软件调用的 WCF 服务,以将错误信息发送到我们的数据库。问题是,由于它是一个在线服务,它不安全,所以我想知道该服务是否可以请求密码(即当我们调用该服务时,我们必须配置密码或类似的东西)。

我在谷歌上搜索过,但对于这么简单的事情来说,这一切似乎都太复杂了……你们能帮帮我吗?

编辑:

这个想法是通过我的软件进行身份验证,而不需要用户登录。

【问题讨论】:

您要验证什么?其他软件的用户,还是软件本身?换句话说,您想检查错误报告是来自特定的授权用户,还是只是从您的软件应用程序之一生成? 我想如果我可以认证一个用户,我也可以用同样的方式认证一个软件,对吗?但这个想法是对软件进行身份验证。 【参考方案1】:

另一种选择是实现您自己的安全性。这是一个基本示例。

WCF 服务

在您的服务中,将ServiceBehaviorInstanceContextMode 更改为PerSessionConcurrencyMode 更改为Single

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
public class SomeService : ISomeService
 
    // ...

在您的服务中添加 UsernamePassword 属性。

public string UserName  [OperationContract] get; [OperationContract] set; 
public string Password  [OperationContract] get; [OperationContract] set; 

添加用于检查安全性的私有方法。

public void CheckSecurity()

    if ((this.UserName == null || this.Password == null) ||
        this.UserName == "username" && this.Password == "password"))
    
        throw new FaultException("Unknown username or incorrect password.");
    

然后在你的每个服务类构造函数方法中调用CheckSecurity方法。

public SomeServiceMethod1()

    this.CheckSecurity();

    // some method codes

客户端应用程序

在您的客户端应用程序代码中,为每个实例设置服务用户名和密码,或创建一个静态类来为您执行此操作。

您也可以尝试在用户名和密码中使用加密来增加安全性。

请注意,这只是为您添加另一个可能满足您需求的选项,但您应该始终尝试使用 Microsoft 的做事方式。

【讨论】:

【参考方案2】:

您可以使用 ASP.NET Membership 提供程序对客户端进行身份验证。 There is an article on MSDN describing how to achieve that.

【讨论】:

【参考方案3】:

不幸的是,安全从来都不是简单的。对于您的要求,请查看UserNamePasswordClientCredential 和UserNamePasswordServiceCredential。它们可能就足够了。

【讨论】:

【参考方案4】:

以下所有答案都不错,但这取决于谁在使用您的 WCF 服务。

例如,我知道一个由 iPhone 应用程序通过 REST 使用的 WCF 服务,上面的一些方案即使不是不可能实现也是非常困难的。它使用了类似于 stefan 在消息头中传递会话密钥的解决方案。

【讨论】:

【参考方案5】:

有很多方法可以处理这种情况。

Fredrik 和 stefan 的答案一起可以产生身份验证方法和授权(通过令牌),但您必须自己编写登录页面、数据库、代码、检查、强制执行、令牌创建、令牌嵌入和令牌验证逻辑。

PaulF 的建议可能工作量较少,因为您可以使用 WCF 内置的功能在消息传输中携带凭据。可以跳过令牌创建、令牌嵌入和令牌验证逻辑部分。

如果您计划支持许多不同的设备,我建议您研究 OpenID、Windows Identity Foundation、Azure 身份验证服务等。 - 这些设置有点复杂,但提供了一种可靠、基于标准且灵活的方法来传递凭据。如果你想走这条路,被动联合是一个很好的关键字。

不幸的是,正如保罗所说,安全从来都不是简单的。您必须考虑如何进行身份验证,您需要了解有关服务/应用程序中的人的信息,如何安全地将这些凭据传递给其他应用程序/服务,他们如何知道您真的是您,反之亦然……一旦您获得联合身份验证设置,您不再需要为此服务和其他未来服务担心很多这些事情......

【讨论】:

【参考方案6】:

对生成服务请求的软件进行身份验证本质上是一个非常困难的问题,比对人类用户进行身份验证要困难得多。问题源于需要存储秘密信息,以用于构建作为身份验证基础发送的凭证。

在对人类用户进行身份验证时,您可以相信他们能够将机密(例如 PIN 或密码)存储在只有他们可以访问的数据存储(他们耳朵之间的湿灰质)中。

当您尝试对在您无法控制的环境中执行的某些软件进行身份验证时,没有等效的密钥存储位置可让您确保只有您的软件可以访问它。因此,一般来说,您的软件无法生成可靠地证明它是由您的软件生成的请求,而不是由其他东西生成的请求。

您唯一的选择是:

想办法在运行时为软件提供秘密存储,例如必须与客户端应用程序结合使用的受 PIN 保护的智能卡。 依靠默默无闻的安全性,接受这只会使攻击者的欺骗更加困难和耗时,但不会击败决心破坏您的身份验证方案的人。

【讨论】:

【参考方案7】:

您需要实现自定义密码验证。 以下是关于此的好文章: UserNamePasswordValidator 和 CodeProject。

我们在项目中使用相同的东西,但使用 API 密钥而不是用户名。在这种情况下,密码可以是任何东西。

【讨论】:

以上是关于如何在 WCF 服务上设置密码?的主要内容,如果未能解决你的问题,请参考以下文章

Redis如何设置密码?

iis部署wcf服务过程

如何在 Ubuntu上使用 Nginx 设置密码验证

如何在 Ubuntu上使用 Nginx 设置密码验证

如何在 Ubuntu上使用 Nginx 设置密码验证

如何设置 Ubuntu 14.04 的 SSH 无密码登录