Search code examples
wcfwcf-binding

Enable Token to my already working REST Service


I have created REST Service, it works fine. When I call a method I will send me Json response.

Now I want to enable Token. I write code to generate Token and run it. It gives me following Error:

Contract requires Session, but Binding 'WebHttpBinding' doesn't support it or isn't configured properly to support it.

Please let me know what are the changes required to fix this issue.

Web Config

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="Service.Service" behaviorConfiguration="serviceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="Service.IService" behaviorConfiguration="web"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehavior">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

Service Class Interface

[ServiceContract(SessionMode = SessionMode.Required)]
//[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(
        Method = "GET",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "GetStudent")]
    string GetStudent();

    [OperationContract]
    [WebInvoke(
        Method = "POST",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "AuthenticateUser")]
    string AuthenticateUser(string user, string pwd);
}

Service Implementation Class

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
//[ServiceBehavior]
public class Service : IService
{
    string UserToken = string.Empty;
    public bool IsValidateUser()
    {
        //Getting the user token from client request
        if (OperationContext.Current.IncomingMessageHeaders.FindHeader("TokenHeader", "TokenNameSpace") == -1)
        {
            return false;
        }

        string userIdentityToken = Convert.ToString(OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("TokenHeader", "TokenNameSpace"));

        //Authenticating user with token, if it is validated then returning employee data
        if (userIdentityToken == UserToken)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public string GetStudent()
    {

       JavaScriptSerializer js = new JavaScriptSerializer();
       return js.Serialize(Student.GetStudent());

    }

    public string AuthenticateUser(string user, string pwd)
    {
        if (!(string.IsNullOrEmpty(user)) && !(string.IsNullOrEmpty(pwd)))
        {
            UserToken = OperationContext.Current.SessionId;
        }
        return UserToken;
    }
}

Solution

  • I found another solution which is I have created a custom(combination of some values) encrypted token. And it works fine. I have to use database approach to use it.