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

时间:2019-08-06 14:29:02

标签: wcf authentication wcf-rest

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

2 个答案:

答案 0 :(得分: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,则应使用Webhttpbinding替换WSHttpbinding。
在设置连接字符串之前,我们应该安装asp.net sql成员资格提供程序。通常位于“ C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319”文件夹中。
Aspnet_regsql.exe实用程序。
enter image description here
这是一个简单的教程。
http://mahedee.net/asp-net-membership-step-by-step/
这是一个官方的例子。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/membership-and-role-provider
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-membership-provider
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-role-provider-with-a-service
随时让我知道问题是否仍然存在。

答案 1 :(得分:1)

这是我没有服务配置的解决方案。如果您已在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中使用的

相关问题