Consuming a secured JWT webapi using ionic, angular 2

Author: Shahim Sadakath


I had a requirement to create an app which consumes a secured JWT webapi using ionic and angular 2. This is how I did it. Hope you like.


Reference : http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/


1) Open Startup.cs and paste the following code

using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.Jwt;
using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Http;

[assembly: OwinStartup(typeof(SecuredWebAPI.Startup))]
namespace SecuredWebAPI
{
    public class Startup
    {
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

        public static string PublicClientId { get; private set; }

        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            ConfigureOAuth(app);
            ConfigureOAuthTokenConsumption(app);

          

            WebApiConfig.Register(config);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
        }

        private void ConfigureOAuthTokenConsumption(IAppBuilder app)
        {
            //Hosting url
            var issuer = "http://localhost:53726";
            string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
            byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]);

            // Api controllers with an [Authorize] attribute will be validated with JWT
            app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    AllowedAudiences = new[] { audienceId },
                    IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                    {
                        new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
                    }
                });
        }
        public void ConfigureOAuth(IAppBuilder app)
        {
                   

            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                //For Dev enviroment only (on production should be AllowInsecureHttp = false)
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorizationServerProvider(),
                AccessTokenFormat = new CustomJwtFormat("http://localhost:53726") //Hosing Url
            };

            // OAuth 2.0 Bearer Access Token Generation
            app.UseOAuthAuthorizationServer(OAuthServerOptions);

        }

    }
}


2) Create CustomJwtFormat.cs and paste the following code

using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Web;
using Thinktecture.IdentityModel.Tokens;

namespace SecuredWebAPI
{
    public class CustomJwtFormat : ISecureDataFormat
    {

        private readonly string _issuer = string.Empty;

        public CustomJwtFormat(string issuer)
        {
            _issuer = issuer;
        }

        public string Protect(AuthenticationTicket data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];

            string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["as:AudienceSecret"];

            var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);

            var signingKey = new HmacSigningCredentials(keyByteArray);

            var issued = data.Properties.IssuedUtc;

            var expires = data.Properties.ExpiresUtc;

            var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);

            var handler = new JwtSecurityTokenHandler();

            var jwt = handler.WriteToken(token);

            return jwt;
        }

        public AuthenticationTicket Unprotect(string protectedText)
        {
            throw new NotImplementedException();
        }
    }
}

3) Open web.config and add the following app settings

<!-- You can modify these if you want -->

 

<!-- You can modify these if you want -->

 
  

 
Now we will look at the client to consume this web api, I am not going to include all the angular 2 code here. I will just add the service and login codes. Remember you need 

<!-- You can modify these if you want -->

angular2-jwt to consume this web api through generated access token.


1) Security.service.ts 

import { Injectable } from '@angular/core';

import {Http,Headers} from '@angular/http';

import { AppSettings } from '../app.settings';

import { LoginData,CurrentUserInfo } from '../app.common';

import {Observable} from 'rxjs/Observable';

import { AuthHttp } from 'angular2-jwt';


@Injectable()

export class SecurityService {

public currentUserInfo:CurrentUserInfo;

constructor(private http: Http,private authHttp:AuthHttp) {

this.currentUserInfo = new CurrentUserInfo();

}


login(loginData:LoginData) : any {

var headers = new Headers();

headers.append('Content-Type', 'application/x-www-form-urlencoded');


var credentials = "grant_type=password"

+ "&userName=" + loginData.userName

+ "&password=" + loginData.password;



return this.http.post(AppSettings.API_ENDPOINT +'/token', credentials, { headers: headers });




}


}</code></pre>

<p><br />
<strong>2) Login.ts </strong></p>

<pre>
<code class="language-cs">import { Component, ViewChild } from '@angular/core';

import { Nav, Platform } from 'ionic-angular';

import { StatusBar } from '@ionic-native/status-bar';

import { SecurityService } from '../../app/services/security.service'

import { LoginData, CurrentUserInfo } from '../../app/app.common'

import { AuthHttp,JwtHelper } from 'angular2-jwt';

import { AppSettings } from '../../app/app.settings';



@Component({

selector:'login',

templateUrl:'login.html',

providers: [SecurityService]

})


export class LoginPage {


private message:string;

private loginData:LoginData;



constructor(private secService:SecurityService,private authHttp:AuthHttp){

this.loginData = new LoginData();

}


login(loginData)

{

this.secService.login(loginData).subscribe((res) => {

var resObj = res.json();

if (typeof resObj.access_token != "undefined")

{

this.secService.currentUserInfo.isLoggedIn = true;

localStorage.setItem('access_token',resObj.access_token);


var jwtHelper = new JwtHelper();




localStorage.setItem('loginKey',jwtHelper.decodeToken(resObj.access_token).loginKey);


this.message = "Successfull Login";

this.authHttp.get(AppSettings.API_ENDPOINT +'/api/User/GetFunctions?loginKey='+localStorage.getItem('loginKey'))

.subscribe((res)=> {console.log(res);});

}

else

{

this.secService.currentUserInfo.isLoggedIn = false;

this.message = "login Failed!!! "+

JSON.parse(resObj._body).error_description;

}

},(error)=>{

this.secService.currentUserInfo.isLoggedIn = false;

this.message = "login Failed!!! "+ error;

});

}

}

 

 

 



Tags: webapi JWT
Views: 29

Comments

Please login or register to post a comment.


There are currently no comments.