简体   繁体   English

WCF服务中的ASP.NET成员身份验证

[英]ASP.NET Membership Authentication in WCF service

I am trying to extend an existing ASP.NET application with a WCF service. 我正在尝试使用WCF服务扩展现有的ASP.NET应用程序。 The service must require authentication via the same Membership Provider that the rest of the site uses. 该服务必须要求站点其余部分使用相同的成员资格提供程序进行身份验证。

Here's the web.config file: 这是web.config文件:

<configuration>
<system.web>
  <compilation debug="true" targetFramework="4.5.2" />
  <httpRuntime targetFramework="4.5.2" />
  <authentication mode="Forms">
    <forms name=".MyAppAuthentication" timeout="5760" slidingExpiration="true" />
  </authentication>
  <roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">
    <providers>
      <clear />
      <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="UsersContext" applicationName="MyApp" />
    </providers>
  </roleManager>
  <membership defaultProvider="AspNetSqlMembershipProvider">
    <providers>
      <clear/>
      <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="UsersContext" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="10" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="MyApp"/>
    </providers>
  </membership>
</system.web>
<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  <bindings>
    <wsHttpBinding>
      <binding name="MembershipBinding">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="UserName"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MembershipBehaviour">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false"/>
        <serviceAuthorization roleProviderName="AspNetSqlRoleProvider" principalPermissionMode="UseAspNetRoles" />
        <serviceCredentials>
          <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="AspNetSqlMembershipProvider" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <services>
    <service name="ServiceTestBackend.Services.TestService" behaviorConfiguration="MembershipBehaviour">
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="MembershipBinding" contract="ServiceTestBackend.Services.ITestService" />
    </service>
  </services>
</system.serviceModel>
<connectionStrings>
  <add name="UsersContext" connectionString="data source=.;initial catalog=MyApp.Accounts;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>

The code of the service is very simple: 服务的代码非常简单:

public class TestService : ITestService
{
    public string FindUser()
    {
        var user = Membership.GetUser();
        return user.UserName;
    }
}

And the client is just about as simple 和客户一样简单

var client = new TestService.TestServiceClient();
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
var acc = client.FindUser();

The server is invoked, but the method fails because Membership.GetUser() returns null . 调用了服务器,但是该方法失败,因为Membership.GetUser()返回null

Am I missing anything in the configuration? 我在配置中缺少任何内容吗?

I think there is some confusion here. 我认为这里有些混乱。 I am not sure what you want to do exactly. 我不确定您要做什么。 You can make this really simple by doing this. 通过执行此操作,您可以使其变得非常简单。

  public class TestService : ITestService
  {
     public string FindUser(string userName, string password)
     {
        var user = Membership.GetUser(username, password);
        return (user!=null?user.userName: string.Empty);
     }
 }

Your client should look like; 您的客户应该看起来像;

 using(var client = new TestService.TestServiceClient())
 {
     var response = client.FindUser(username, password);
     //validate the response
 }
  • Try code like this : 试试这样的代码:
public string FindUser()
{
   if (ServiceSecurityContext.Current != null)
       return ServiceSecurityContext.Current.PrimaryIdentity.Name;
   return null;
}
  • You may as well get user name from : 您也可以从获得用户名:
IPrincipal principal = Thread.CurrentPrincipal;
String user = principal.Identity.Name
  • And last if you really want to get name from HttContext.Current.User or Membership.GetUser() - because you ve got much existing code - you may write Custom Module for Authentication : 最后,如果您真的想从HttContext.Current.UserMembership.GetUser()获取名称-因为您有很多现有代码-您可以编写用于身份验证的自定义模块:

Look at my post : https://stackoverflow.com/a/33523683/5295797 看看我的帖子: https : //stackoverflow.com/a/33523683/5295797
And read carefully section Implementation of the module. 并仔细阅读模块的实现部分。
There is also the full project that can be downloaded from a link in that post. 也可以从该帖子中的链接下载完整的项目。

Regards 问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM