How to Implement custom authentication in WCF service

眉间皱痕 提交于 2021-01-29 11:23:12

问题


I would like to create WCF restful service for mobile application with custom authentication. First request should be login, specially client sending username, password and getting access token. Then all other requests should be check access token. Also for authentication I would like to use asp.net membership provider in other words to use Forms based authentication.


回答1:


At first, we should configure the Asp.net SQL membership Provider. Then we should use Username/password security mode so that authenticate the client with custom credential. Please refer to the below configuration.

<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>

If we use WCF to create Restful Service, we should replace the WSHttpbinding with Webhttpbinding.
Before setup the connection string, we should install the asp.net sql membership provider. it ordinarily located in the “C:\Windows\Microsoft.NET\Framework64\v4.0.30319” folder.
Aspnet_regsql.exe utility.

Here is a simple tutorial.
http://mahedee.net/asp-net-membership-step-by-step/
Here is an official example.
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
Feel free to let me know if the problem still exist.




回答2:


Here is my solution without service configuration. If you have configured asp-net membership provider in web.config.

[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() specific to may environment, specially I'm using in SharePoint.



来源:https://stackoverflow.com/questions/57378352/how-to-implement-custom-authentication-in-wcf-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!