1
votes

I followed the following tutorial and set up my azure backend .

https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/custom/

I then installed postman for the first time and set :

http://apptest.azurewebsites.net/.auth/login/custom

{"username" : "adrian" , "password" : "supersecret"}

Json (application/json)

However , i keep getting this error :

405 Method not Allowed

{
  "Message": "The requested resource does not support http method 'GET'."
}

Backend Code :

using System;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Web.Http;
using Newtonsoft.Json;
using AppTestService.Models;
using AppTestService.DataObjects;

using Microsoft.Azure.Mobile.Server.Login;


namespace AppTestService.Controllers
{
    [Route(".auth/login/custom")]
    public class CustomAuthController : ApiController
    {
        private AppTestContext db;
        private string signingKey, audience, issuer;

        public CustomAuthController()
        {
            db = new AppTestContext();
            signingKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
            var website = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME");
            audience = $"https://{website}/";
            issuer = $"https://{website}/";
        }

        [System.Web.Http.HttpPost]
        public IHttpActionResult Post([FromBody] User body)
        {
            if (body == null || body.Username == null || body.Password == null ||
                body.Username.Length == 0 || body.Password.Length == 0)
            {
                return BadRequest();
            }

            if (!IsValidUser(body))
            {
                return Unauthorized();
            }

            var claims = new Claim[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, body.Username)
            };

            JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
                claims, signingKey, audience, issuer, TimeSpan.FromDays(30));
            return Ok(new LoginResult()
            {
                AuthenticationToken = token.RawData,
                User = new LoginResultUser { UserId = body.Username }
            });
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool IsValidUser(User user)
        {
            return db.Users.Count(u => u.Username.Equals(user.Username) && u.Password.Equals(user.Password)) > 0;
        }


    }


    public class LoginResult
    {
        [JsonProperty(PropertyName = "authenticationToken")]
        public string AuthenticationToken { get; set; }

        [JsonProperty(PropertyName = "user")]
        public LoginResultUser User { get; set; }
    }

    public class LoginResultUser
    {
        [JsonProperty(PropertyName = "userId")]
        public string UserId { get; set; }
    }


}

If i add [System.Web.Http.HttpGet] on top of the function , then i get a different error. :

415 Unsupported media type

{
  "Message": "The request contains an entity body but no Content-Type header. The inferred media type 'application/octet-stream' is not supported for this resource."
}

These are the headers :

Allow →POST
Content-Length →72
Content-Type →application/json; charset=utf-8
Date →Sat, 28 Jan 2017 22:08:48 GMT
Server →Microsoft-IIS/8.0
X-Powered-By →ASP.NET
3
Are you passing the content-type in your request? - Ali Baig
There are two errors you are getting both related to GET. When you send POST request with Content-Type = "application/json" what error you are getting? - Chetan

3 Answers

0
votes

You probably do want to make a POST request from PostMan instead of a GET. Don't add [HttpGet] on the action, just set the method to POST in PostMan.

And make sure you set the header Content-Type: application/json in PostMan.

0
votes

Make sure in the headers of your request you are setting ContentType = "application/json" in postman or even when creating a request from any client.

Change your controller definition to

[RoutePrefix("auth/login/custom")]
public class CustomAuthController : ApiController
{
}

And just for test, introduce a route on POST like

[System.Web.Http.HttpPost]
[Route("post")]
public IHttpActionResult Post([FromBody] User body)

and try making a request to

http://apptest.azurewebsites.net/auth/login/custom/post

0
votes

In Azure service api make sure it is with [HttpPost]. If you are able to send body param that means you have selected Post in postman while calling API which is correct. Dont change either of postman call or azure api to get. it will be mismatch.

If you have access to azure logs check if http Post is redirected to the https url as Get, in this case try calling https directly.

Azure logs looks as follows in this case:

Received request: POST http://xxx.azurewebsites.net/api/Data/test
Information Redirecting: https://xxx.azurewebsites.net/api/Data/test
Received request: GET https://xxx.azurewebsites.net/api/Data/test

in this case call https://xxx.azurewebsites.net/api/Data/test