This is my second article on the Web API Token. As we have seen in the first article, in this article I will try to primarily focus on Token generation, refresh token generation and authorization using the generated token. We have already learned about the OAuthorizationServerOptions. We will again learn in another way, this time we will cover all these things in a web based MVC API application using Knockout js. So let's try to learn step-by-step.
Prerequisites
- Visual Studio 2013
- SQL Server
Step 1
Start Visual Studio 2013 and select a new project.
Step 2
Choose the Web API template along with MVC and check that the Authentication type would be Individual User Account.
Step 3
Now we can move to the coding part, so before we do the coding, let's try to understand some basic concepts or terminology used in OAuth 2. They are the following.
- Resource Owner
- Resource Server
- Access Token
- Bearer Token
Bearer Token
This is a type of access specifier used to authenticate the user. Bearer tokens are only used over HTTPS.
Access Token
An Access Token is a token that grants the access of resources.
Resource Server
A server that hosts the resources.
Resource Owner
Resource owners are those that can get access to the resource (a user).
Now flip into the Visual Studio 2013 and open the Starup.Auth.cs file. In the pre-generated code we can see there is a Token field. Now we can additionally call the Refresh Token. Let's see.
Use the Microsoft.Owin.Security.Infrstructure namespace in the project. Apart from that we need to also define the OnCreate and OnRecieve methods for the RefereshToken. See the following code.
- public void ConfigureAuth(IAppBuilder app)
- {
- app.CreatePerOwinContext(ApplicationDbContext.Create);
- app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
- app.UseCookieAuthentication(new CookieAuthenticationOptions());
- // app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
- PublicClientId = "self";
- OAuthOptions = new OAuthAuthorizationServerOptions
- {
- TokenEndpointPath = new PathString("/Token"),
- Provider = new ApplicationOAuthProvider(PublicClientId),
- RefreshTokenProvider = new AuthenticationTokenProvider()
- {
- OnCreate = CreateRefreshToken,
- OnReceive = RecieveRefreshToken
- },
- AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
- AccessTokenExpireTimeSpan = TimeSpan.FromDays(10),
- AllowInsecureHttp = true,
-
- };
-
- app.UseOAuthBearerTokens(OAuthOptions);
- }
-
- private static void RecieveRefreshToken(AuthenticationTokenReceiveContext obj)
- {
- //throw new NotImplementedException();
- obj.DeserializeTicket(obj.Token);
- }
-
- private static void CreateRefreshToken(AuthenticationTokenCreateContext obj)
- {
- // throw new NotImplementedException();
- obj.SetToken(obj.SerializeTicket());
- }
Step 4
Install the Knockout.js from Nuget.
Step 5
Make an App.Js file.
- function ViewModel() {
- var self = this;
-
- var tokenKey = 'accessToken';
- var RefTokenKey = 'refreshToken';
- self.result = ko.observable();
- self.user = ko.observable();
-
- self.registerEmail = ko.observable();
- self.registerPassword = ko.observable();
- self.registerPassword2 = ko.observable();
-
- self.loginEmail = ko.observable();
- self.loginPassword = 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);
-
- sessionStorage.setItem(tokenKey, data.access_token);
- var tkn = sessionStorage.getItem(tokenKey);
- $("#tknKey").val(tkn);
- }).fail(showError);
- }
-
- }
-
- var app = new ViewModel();
- ko.applyBindings(app);
Step 6
Open the Index page and design the registration and login form. So for that we can see the authorization using a token, also we can see the generated token and refresh token too.
- @section Scripts {
- @Scripts.Render("~/bundles/App")
- }
- <div class="row alert-danger breadcrumb">
- <div class="col-sm-6">
- <form data-bind="submit: callApi">
- <h3>Invoke API</h3>
- <div class="form-group">
- <label>User</label>
- <input class="form-control" type="text" readonly data-bind="value: user" />
- </div>
- <div class="form-group">
- <label>Result</label>
- <input class="form-control" type="text" readonly data-bind="value: result" />
-
- </div>
- <div class="form-group">
- <button type="submit" class="btn btn-default">Call API</button>
- </div>
- </form>
- </div>
- </div>
Step 7
Now flip into the BundleConfig.cs file and add the App.js file inside it.
Step 8
Call that bundle App.js file inside the Index page.
Now we can use the token-based authentication.
Now we can use any resource, if the resource is in " [Authorize]" using these tokens. If the token is wrong or expired then that resource will not allow us to use it.