0

I am trying to implement a custom authentication scheme in my OData WCF service, where the client submits their login credentials to the server, and receives a session token if they are authenticated.

In the OData service, I have a Login method:

[WebInvoke]
public void Login()
{
    HttpRequest request = HttpContext.Current.Request;
    string user, password;

    user = request.Form["User"];
    password = request.Form["Password"];
    //...
}

which I call from the client using jQuery:

$.ajax({
    url: loginUrl,
    type: 'POST',
    data: JSON.stringify({ User: loginID(), Password: loginPassword() }),
    dataType: 'json',
    contentType: 'application/json; charset=utf-8'
});

In the browser, I can see that User and Password are present in the POST body.

Stepping through the OData service, the Login() method is being hit, but User and Password are not there - the request.Form is completely empty.

At first, searching found this question, saying that the POST content type needs to be set to application/json instead of application/x-www-form-urlencoded. However, making this change did not solve the problem.

Searching found many SO questions about OData or WCF POST requests being empty, but I eventually found the MSDN page on WCF service operations, which states:

The operation method may only accept input parameters. Data sent in the message body cannot be accessed by the data service.

So according to this, a POST request won't work no matter what. This seems to mean I will have to use a GET request. However, sending the password in a GET request is a bad idea.

Do I need to use "faux" HTTP Basic Authentication, where I pass the credentials in a header, but only for the login call, and not with every request?

Otherwise, what is the proper way to get the login credentials from the client to the OData service?

Community
  • 1
  • 1
Aaroninus
  • 1,062
  • 2
  • 17
  • 35

1 Answers1

1

Otherwise, what is the proper way to get the login credentials from the client to the OData service?

The proper way is to separate the authentication from the OData service. Basically you need to create an endpoint for your service e.g. /token based on OAuth to which you pass the user credentials in a post call with

grant_type=password&username=... &password=... 

and then receive an access token which you will subsequently pass in the header of your OData calls

Authorization: Bearer <access_token>

The OData controller itself doesn't handle the authentication and token creation.

There is a very good series of tutorials by Taiseer Joudeh which I recommend to read: http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/

jps
  • 20,041
  • 15
  • 75
  • 79