ASP.Net WebAPI Owin Authentication Attribute knocked out

I am trying to create a demo project that uses .Net ASP.Net WebAPI and KnockoutJs as an interface. I have created controller methods that listen for message / token and validate the user and return a token. This is done from the Ajax Post from the knockout view model.

This code works. However, when I get 200 back (Success) from webApi, I then redirect to the controller method decorated with [Authorize]. And where I hit 401 - not authorized.

Login()
    {
        var data = {
            username : this.login.emailAddress(),
            password : this.login.password(),
            RememberMe: this.login.rememberMe(),
            grant_type: "password"
        }

        return $.ajax({
            type: "POST",
            data: data,
            dataType: "json",
            url: "/token",
            contentType: "application/json"
        }).done((reply) => {
            window.location.href = "/Home/AnotherThing";
        });

    }

      

I think the problem is that I am getting a response from my / token (login) but not doing anything with it. I'm not sure what to do with the token. I foolishly thought that Oout somehow put a token in my headers and they'll be magical there. I was wrong.

So I was looking for an example and then the best way is to find Here

But this means that I will have a lot of repetitive code, on each view model

Extract:

function ViewModel() {  
    var self = this;  

    var tokenKey = 'accessToken';  
    var RefTokenKey = 'refreshToken';  
    self.result = ko.observable();  
    self.user = ko.observable();  

    self.token = ko.observable();  
    self.refreshToken = ko.observable();  

    function showError(jqXHR) {  
        self.result(jqXHR.status + ': ' + jqXHR.statusText);  
    }  

    self.callApi = function () {  

        self.result('');  

        var token = sessionStorage.getItem(tokenKey);  

        var headers = {};  
        if (token) {  
            headers.Authorization = 'Bearer ' + token;  
        }  

        $.ajax({  
            type: 'GET',  
            url: '/api/values',  
            headers: headers  
        }).done(function (data) {  
            self.result(data);  
        }).fail(showError);  
    }  

    self.callToken = function () {  
        self.result('');  
        var loginData = {  
            grant_type: 'password',  
            username: self.loginEmail(),  
            password: self.loginPassword()  
        };  

        $.ajax({  
            type: 'POST',  
            url: '/Token',  
            data: loginData  
        }).done(function (data) {  
            self.user(data.userName);  
            // Cache the access token in session storage.  
            sessionStorage.setItem(tokenKey, data.access_token);  
            var tkn = sessionStorage.getItem(tokenKey);  
            $("#tknKey").val(tkn);  
        }).fail(showError);  
    }  

}  

var app = new ViewModel();  
ko.applyBindings(app);

      

This seems to be part of what I am missing:

sessionStorage.setItem(tokenKey, data.access_token);  
                var tkn = sessionStorage.getItem(tokenKey);  
                $("#tknKey").val(tkn);  

      

Do I need each view model to have code that is then sent to sessionStorage and receives a token?

So this:

var token = sessionStorage.getItem(tokenKey);  

        var headers = {};  
        if (token) {  
            headers.Authorization = 'Bearer ' + token;  
        }  

        $.ajax({  
            type: 'GET',  
            url: '/api/values',  
            headers: headers  
        }).done(function (data) {  
            self.result(data);  
        }).fail(showError);  
    } 

      

Seems like a lot of code. Is it correct?

+3


source to share


1 answer


So what you can do is attach a bearer token to each of your HTTP requests. I'm assuming you are using jQuery? Use a config optionbeforeSend

if possible .

Extract the reuse method like:

function onBeforeSend(xhr, settings) {    
  var token = sessionStorage.getItem(tokenKey);  

  if (token) {  
    xhr.setRequestHeader('Authorization', 'Bearer ' + token ); 
  }  
}

      

And then just attach this method to each of your calls $.ajax

that require a token, for example:



$.ajax({  
  type: 'GET',  
  url: '/api/values',  
  headers: headers,
  beforeSend: onBeforeSend
}).done(function (data) {  
  self.result(data);  
}).fail(showError);  

      

The function onBeforeSend

obviously needs to be accessible by your ajax call (I'm not a knockout, so I don't know if it has any constructs like services, but if not, you can, for example, to not make it a global function. but your code organization is up to you).

This way, you will need to add a bit beforeSend: onBeforeSend

for each request that requires authorization, and this will avoid unnecessary duplication of code.

+3


source







All Articles