Search code examples
asp.netasp.net-mvcasp.net-web-apioauth-2.0asp.net-identity

Authentication from asp.net app to api, Oauth


For the sake of understanding this I'm using a sample app from asp.net and when I run it and use the sample page they have, everything works great.

Then I create a new empty asp.net project with mvc scaffolding enabled, and I recreate the scenario with 2 different layers. I'm able to register by using this form action:

    <form method="post" action="https://localhost:44305/api/Account/Register">
        <h3>Register</h3>
        <div class="form-group">
            <label>Email</label>
            @Html.TextBoxFor(m => m.Email, new { id = "txtUserName", @class = "form-control" })
        </div>
        <div class="form-group">
            <label>Password</label>
            @Html.PasswordFor(m => m.Password, new { id = "txtPassword", @class = "form-control" })
        </div>
        <div class="form-group">
            <label>Confirm Password</label>
            @Html.PasswordFor(m => m.ConfirmPassword, new { id = "txtConfirmPassword", @class = "form-control" })
        </div>
        <div class="form-group">
            <button type="submit" class="btn btn-default">Register</button>
        </div>
    </form>

but when I try to Login it redirects to the same page with username/password I entered as query strings: (http://localhost:57972/?Email=username&Password=password)

        <div class="form-group">
            <label>Email</label>
            @Html.TextBoxFor(m => m.Email, new { id = "txtloginUserName", @class = "form-control" })
        </div>
        <div class="form-group">
            <label>Password</label>
            @Html.PasswordFor(m => m.Password, new { id = "txtloginPassword", @class = "form-control" })
        </div>
        <div class="form-group">
            <button id="btnLogin" class="btn btn-default">Log In</button>
        </div>
<script>
    var token = "";
    $('#btnLogin').click(function () {
        var username = $('#txtloginUserName').val();
        var password = $('#txtloginPassword').val();

        $.ajax({
            type: 'POST',
            url: 'http://localhost:26812/Token',
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
            data: {
                grant_type: 'password',
                username: username,
                password: password
            },
            success: function (data) {
                token = data.access_token;
            }
        })
    });
</script>

** Update

I realized I had to call the full url for /Token and now when I log in and watch the network packet it responds with a 200 OK status code, but then pops up an error in console: "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:57972' is therefore not allowed access."

I've added config.EnableCors() into my webapiconfig, and I've added the annotation on my apicontroller to allow all for testing purposes:

[EnableCors(origins: "*", headers:"*", methods:"*")]

Picture of the network response and error:


Solution

  • Try adding this method to your Global.asax :

    protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE, PUT");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Authentication");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "86400");
                HttpContext.Current.Response.End();
            }
            else
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE");
            }
        }