如何在 WCF 服务中实现自定义身份验证

Posted

技术标签:

【中文标题】如何在 WCF 服务中实现自定义身份验证【英文标题】:How to Implement custom authentication in WCF service 【发布时间】:2019-12-14 03:26:43 【问题描述】:

我想为具有自定义身份验证的移动应用程序创建 WCF restful 服务。第一个请求应该是登录,特别是客户端发送用户名、密码和获取访问令牌。然后所有其他请求都应该检查访问令牌。同样对于身份验证,我想使用 asp.net 会员提供程序,换句话说,使用基于表单的身份验证。

【问题讨论】:

【参考方案1】:

首先,我们应该配置 Asp.net SQL 成员资格提供程序。然后我们应该使用用户名/密码安全模式,以便使用自定义凭据对客户端进行身份验证。 请参考以下配置。

<connectionStrings>
    <add name="SqlConn" connectionString="server=myserver;database=aspnetdb;uid=sa;password=123456;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <system.web>
    <membership defaultProvider="SqlMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear />
        <add
          name="SqlMembershipProvider"
          type="System.Web.Security.SqlMembershipProvider"
          connectionStringName="SqlConn"
          applicationName="WcfService2"
          enablePasswordRetrieval="false"
          enablePasswordReset="false"
          requiresQuestionAndAnswer="false"
          requiresUniqueEmail="true"
          passwordFormat="Hashed" />
      </providers>
    </membership>
    <roleManager enabled ="true"
                 defaultProvider ="SqlRoleProvider" >
      <providers>
        <add name ="SqlRoleProvider"
             type="System.Web.Security.SqlRoleProvider"
             connectionStringName="SqlConn"
             applicationName="WcfService2"/>
      </providers>
    </roleManager>
    <compilation debug="true" targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding>
          <security mode="Message">
            <message clientCredentialType="UserName"></message>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlRoleProvider">
          </serviceAuthorization>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlMembershipProvider"/>
            <serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="974ad39ff0b86210f5e7d661e56945ad5c2d3770"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="wsHttpBinding" scheme="http" />
</protocolMapping>

如果我们使用WCF创建Restful Service,我们应该将WSHttpbinding替换为Webhttpbinding。 在设置连接字符串之前,我们应该安装 asp.net sql 成员资格提供程序。它通常位于“C:\Windows\Microsoft.NET\Framework64\v4.0.30319”文件夹中。Aspnet_regsql.exe 实用程序。 这是一个简单的教程。http://mahedee.net/asp-net-membership-step-by-step/ 这是一个官方的例子。https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/membership-and-role-providerhttps://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-membership-providerhttps://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-role-provider-with-a-service 如果问题仍然存在,请随时告诉我。

【讨论】:

我写了更多可用的解决方案。有兴趣可以发帖。 好的。您可以发布一个新问题,以便我们解决特定问题。 (^.^) 兄弟,如果您觉得上面的回复有用,请把它标记为有用,以便其他人愿意接受。此外,如果您在阅读上述文档后遇到新问题,请发布新主题。【参考方案2】:

这是我没有服务配置的解决方案。如果您在 web.config 中配置了 asp-net 会员提供程序。

[ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class SPHostedWCFService 
    
        [OperationContract]
        [WebGet(UriTemplate = "Login?username=username&password=password", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public void Login(string username, string password)
        
            FormsAuthenticationTicket ticket = null;
            MembershipProvider membershipProvider = GetMembershipProvider();
            if (membershipProvider.ValidateUser(username, password))
            
                SPUser user = RunWithEP.web.EnsureUser(username);
                ticket = new FormsAuthenticationTicket( 1, username, DateTime.Now, DateTime.Now.AddDays(1), true, user.ID.ToString());   
            
            if (ticket != null)
            
                string encryptedTicket = FormsAuthentication.Encrypt(ticket);
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                HttpContext.Current.Response.Cookies.Add(cookie);
            
            else
            
                HttpContext.Current.Response.Write("Username or password incorrect.");
            
        

        [OperationContract]
        [WebGet(UriTemplate = "DoWork", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        [PrincipalPermission(SecurityAction.Demand, Authenticated = false)]
        public string DoWork()
        
            if (HttpContext.Current.Request.IsAuthenticated)
            
                return "authenticated request";
            
            else
            
                HttpContext.Current.Response.Write("Username not authenticated.");
                return "not authenticated request";
            
        
    

GetMembershipProvider() 特定于可能的环境,特别是我在 SharePoint 中使用的。

【讨论】:

以上是关于如何在 WCF 服务中实现自定义身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC 5 中实现自定义身份验证

如何在 webflux 中实现自定义身份验证管理器时对未经授权的请求响应自定义 json 正文

可以在 Firebase 3 中实现自定义身份验证属性并将其与安全安全规则一起使用吗?

如何在 ASP.NET MVC 中实现自定义主体和身份?

如何在 RESTful WCF API 中实现 HMAC 身份验证

WCF、RESTful Web 服务和自定义身份验证