KEMBAR78
Authenticating Angular Apps with JWT | PPTX
1
Authenticating
Angular Apps With JWTs
Discussion Agenda
• OAuth 2.0 Background
• What is a JWT?
• JWT Authentication Token Lifecycle
• HTTP Interceptor design pattern in Angular
2
Background: OAuth 2.0 Bearer Tokens
• OAuth 2.0 is a Token Based Authentication Framework typically used with SPA
apps.
• OAuth 2.0 uses encrypted/encoded token strings instead of passing usernames and
passwords.
• An OAuth 2.0 infrastructure issues tokens to users after authentication. The token
must be saved locally on the client and authorizes the user’s access to resources
(APIs, etc.) for a set amount of time.
• Upon token expiration, the user must log in again to access resources (APIs) with
subsequent HTTP Requests.
• A common way of accessing OAuth 2.0 APIs is using a “Bearer Token”. This is a
single string which acts as the authentication of the API request, sent in an HTTP
“Authorization” header.
3
Sample Bearer Token Payload
In an HTTP Request sent to an API using
OAuth 2.0, the Authorization header
contains the Bearer Token as shown here
4
Bearer Tokens are encrypted/encoded token strings
labeled “Bearer” which are used to validate
authentication claims on the server side.
Bearer 0b79bab50daca910b000d4f1a2b675d604257e42…
JWT is a Token Format used to implement OAuth 2.0
• OAuth 2.0 Bearer Tokens need to contain user identity and timeout information.
• Bearer Tokens are issued by the authorization server, expire and can be reused.
• Bearer Tokens need to be signed so that the resource server can validate them
• JWTs are used with SPA apps as Bearer Tokens for OAuth 2.0 authentication.
5
User
Enterprise
login
API
JWT = JSON Web Tokens
• JSON Web Tokens are called JWTs for abbreviation.
• JWTs are digitally signed JSON payloads. Payloads typically contain user identification info
and a lifespan timestamp for authentication.
• As discussed, JWTs are often created by authentication servers to use as Bearer Tokens.
• Bearer Tokens expire, so Angular apps can use JWTs to define a user session.
• JWTs are convenient, because to confirm a session, all the authentication code needs to do
is validate the token’s signature.
• JWTs contain an encoded header, an encoded payload, and are digitally signed by
encrypting the header and payload with a secret key.
• The authentication code signs and validates JWT signatures, so only the server
(resource server and authenticating server) needs to know the secret key.
6
JWT Structure
7
{
“alg”: “HS256”,
“typ”: “JWT”
}
Header
{
“userId”: “023040506”,
“timeout”: “1234567890000”
}
Payload
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydW
V9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
Base64Url
encoded
Base64Url
encoded
Signature =
HMACSHA256( base64UrlEncode(header) + ".“ base64UrlEncode(payload), secret )
3 Components of a JWT
1. The Header defines the Algorithm and Token Type. (JWT in this case)
{
“alg”: “HS256”,
“typ”: “JWT”
}
2. The Payload contains user information necessary to support the Session. The
Payload typically contains a user ID and an expiration timestamp for authentication.
The Payload is -not- encrypted so it is important to mind its contents!
{
“userId”: “023040506”,
“timeout”: “1234567890000”
}
3. The Signature contains a Message Authentication Code string. To produce a
valid signature, you need the Payload and Header, and a Secret Key which is unique
to your app.
8
The JWT Signature is used to validate claims
• The authenticating party (authentication server and resource server) holds a secret key
string, which is used to create and validate the signatures of JWTs.
• The authentication server uses the SHA256 encryption algorithm and its personal
secret key string to create JWT signatures using the below algorithm:
HMACSHA256( base64UrlEncode(header) + ".“ base64UrlEncode(payload), secret )
• From the browser, the user logs in once through the authentication server, then receives
a personal unique JWT (a “Bearer Token”) with the above unique signature back via an
HTTP Response.
• The browser then only needs to save the JWT Bearer Token in memory, and it can be
used to validate every HTTP Request with the secret key string, thus defining a
session.
9
JWT Bearer Token Lifecycle
10
ServerBrowser
1: User sends username and password to server via
browser 2: Server validates
username and
password.
3: Server generates
JWT Bearer Token
using secret key
4: Server sends Bearer Token back to
browser. Does not include password in
Bearer Token payload
5: Browser saves
Bearer Token in
local storage
6: Browser sends Bearer Token back to server with
HTTP Requests 7: Server decodes
Bearer Token, checks
the timestamp and
validates the signature
using the secret key
8: Server sends back HTTP Response data
if the session is valid.
A valid session = timestamp
has not expired and Bearer
Token signature is valid!
eyJhbGciOiJIUzI1NiIsI
nR5cCI6IkpXVCJ9.eyJ
zdWIiOiIxMjM0NTY3O
DkwIiwibmFtZSI6Ikpva
G4gRG9lIiwiYWRtaW4i
OnRydWV9.TJVA95Or
M7E2cBab30RMHrHDc
EfxjoYZgeFONFh7HgQ
Auth
API
Angular HTTP Interceptor Design Pattern – Step 0
Install a library to your app to use to check if a JWT is expired. I
like angular2-jwt.
npm i --save angular2-jwt
11
Angular HTTP Interceptor Design Pattern – Step 1
Use angular2-jwt in a service.
// src/app/auth/auth.service.ts
import { Injectable } from '@angular/core';
import tokenNotExpired from ‘angular2-jwt’;
@Injectable()
export class AuthService {
public getToken(): string {
return localStorage.getItem('token');
}
public isAuthenticated(): boolean {
// get the token
const token = this.getToken();
// return a boolean reflecting whether or not the token is expired
return tokenNotExpired(null, token);
}
}
12
Angular HTTP Interceptor Design Pattern – Step 2
Create an Interceptor which adds the JWT from local storage to the Authorization
Header in any HTTP Request sent.
// src/app/auth/token.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { Observable } from 'rxjs/Observable’;
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(public auth: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.auth.getToken()}`
}
});
return next.handle(request);
}
}
13
Angular HTTP Interceptor Design Pattern – Step 3
Add our new Interceptor class to the HTTP Interceptors service provider (and add the HTTP
Interceptors service to your app if needed).
// src/app/app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './../auth/token.interceptor’;
@NgModule({
bootstrap: [AppComponent],
imports: [...],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi: true
}
]
})
export class AppModule {}
14
Angular HTTP Interceptor Design Pattern – Step 4
Now when we make any HTTP request, the user’s token will be attached
automatically.
Our TokenInterceptor was added to the HTTP Interceptors array by making
the existing HTTP_Interceptors array use our new class.
Now the application-scoped HTTP Interceptors service will use our new class,
and the Authorization Header with our Bearer Token will be added to every
HTTP Request.
15

Authenticating Angular Apps with JWT

  • 1.
  • 2.
    Discussion Agenda • OAuth2.0 Background • What is a JWT? • JWT Authentication Token Lifecycle • HTTP Interceptor design pattern in Angular 2
  • 3.
    Background: OAuth 2.0Bearer Tokens • OAuth 2.0 is a Token Based Authentication Framework typically used with SPA apps. • OAuth 2.0 uses encrypted/encoded token strings instead of passing usernames and passwords. • An OAuth 2.0 infrastructure issues tokens to users after authentication. The token must be saved locally on the client and authorizes the user’s access to resources (APIs, etc.) for a set amount of time. • Upon token expiration, the user must log in again to access resources (APIs) with subsequent HTTP Requests. • A common way of accessing OAuth 2.0 APIs is using a “Bearer Token”. This is a single string which acts as the authentication of the API request, sent in an HTTP “Authorization” header. 3
  • 4.
    Sample Bearer TokenPayload In an HTTP Request sent to an API using OAuth 2.0, the Authorization header contains the Bearer Token as shown here 4 Bearer Tokens are encrypted/encoded token strings labeled “Bearer” which are used to validate authentication claims on the server side. Bearer 0b79bab50daca910b000d4f1a2b675d604257e42…
  • 5.
    JWT is aToken Format used to implement OAuth 2.0 • OAuth 2.0 Bearer Tokens need to contain user identity and timeout information. • Bearer Tokens are issued by the authorization server, expire and can be reused. • Bearer Tokens need to be signed so that the resource server can validate them • JWTs are used with SPA apps as Bearer Tokens for OAuth 2.0 authentication. 5 User Enterprise login API
  • 6.
    JWT = JSONWeb Tokens • JSON Web Tokens are called JWTs for abbreviation. • JWTs are digitally signed JSON payloads. Payloads typically contain user identification info and a lifespan timestamp for authentication. • As discussed, JWTs are often created by authentication servers to use as Bearer Tokens. • Bearer Tokens expire, so Angular apps can use JWTs to define a user session. • JWTs are convenient, because to confirm a session, all the authentication code needs to do is validate the token’s signature. • JWTs contain an encoded header, an encoded payload, and are digitally signed by encrypting the header and payload with a secret key. • The authentication code signs and validates JWT signatures, so only the server (resource server and authenticating server) needs to know the secret key. 6
  • 7.
    JWT Structure 7 { “alg”: “HS256”, “typ”:“JWT” } Header { “userId”: “023040506”, “timeout”: “1234567890000” } Payload eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydW V9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ Base64Url encoded Base64Url encoded Signature = HMACSHA256( base64UrlEncode(header) + ".“ base64UrlEncode(payload), secret )
  • 8.
    3 Components ofa JWT 1. The Header defines the Algorithm and Token Type. (JWT in this case) { “alg”: “HS256”, “typ”: “JWT” } 2. The Payload contains user information necessary to support the Session. The Payload typically contains a user ID and an expiration timestamp for authentication. The Payload is -not- encrypted so it is important to mind its contents! { “userId”: “023040506”, “timeout”: “1234567890000” } 3. The Signature contains a Message Authentication Code string. To produce a valid signature, you need the Payload and Header, and a Secret Key which is unique to your app. 8
  • 9.
    The JWT Signatureis used to validate claims • The authenticating party (authentication server and resource server) holds a secret key string, which is used to create and validate the signatures of JWTs. • The authentication server uses the SHA256 encryption algorithm and its personal secret key string to create JWT signatures using the below algorithm: HMACSHA256( base64UrlEncode(header) + ".“ base64UrlEncode(payload), secret ) • From the browser, the user logs in once through the authentication server, then receives a personal unique JWT (a “Bearer Token”) with the above unique signature back via an HTTP Response. • The browser then only needs to save the JWT Bearer Token in memory, and it can be used to validate every HTTP Request with the secret key string, thus defining a session. 9
  • 10.
    JWT Bearer TokenLifecycle 10 ServerBrowser 1: User sends username and password to server via browser 2: Server validates username and password. 3: Server generates JWT Bearer Token using secret key 4: Server sends Bearer Token back to browser. Does not include password in Bearer Token payload 5: Browser saves Bearer Token in local storage 6: Browser sends Bearer Token back to server with HTTP Requests 7: Server decodes Bearer Token, checks the timestamp and validates the signature using the secret key 8: Server sends back HTTP Response data if the session is valid. A valid session = timestamp has not expired and Bearer Token signature is valid! eyJhbGciOiJIUzI1NiIsI nR5cCI6IkpXVCJ9.eyJ zdWIiOiIxMjM0NTY3O DkwIiwibmFtZSI6Ikpva G4gRG9lIiwiYWRtaW4i OnRydWV9.TJVA95Or M7E2cBab30RMHrHDc EfxjoYZgeFONFh7HgQ Auth API
  • 11.
    Angular HTTP InterceptorDesign Pattern – Step 0 Install a library to your app to use to check if a JWT is expired. I like angular2-jwt. npm i --save angular2-jwt 11
  • 12.
    Angular HTTP InterceptorDesign Pattern – Step 1 Use angular2-jwt in a service. // src/app/auth/auth.service.ts import { Injectable } from '@angular/core'; import tokenNotExpired from ‘angular2-jwt’; @Injectable() export class AuthService { public getToken(): string { return localStorage.getItem('token'); } public isAuthenticated(): boolean { // get the token const token = this.getToken(); // return a boolean reflecting whether or not the token is expired return tokenNotExpired(null, token); } } 12
  • 13.
    Angular HTTP InterceptorDesign Pattern – Step 2 Create an Interceptor which adds the JWT from local storage to the Authorization Header in any HTTP Request sent. // src/app/auth/token.interceptor.ts import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { AuthService } from './auth/auth.service'; import { Observable } from 'rxjs/Observable’; @Injectable() export class TokenInterceptor implements HttpInterceptor { constructor(public auth: AuthService) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { request = request.clone({ setHeaders: { Authorization: `Bearer ${this.auth.getToken()}` } }); return next.handle(request); } } 13
  • 14.
    Angular HTTP InterceptorDesign Pattern – Step 3 Add our new Interceptor class to the HTTP Interceptors service provider (and add the HTTP Interceptors service to your app if needed). // src/app/app.module.ts import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { TokenInterceptor } from './../auth/token.interceptor’; @NgModule({ bootstrap: [AppComponent], imports: [...], providers: [ { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true } ] }) export class AppModule {} 14
  • 15.
    Angular HTTP InterceptorDesign Pattern – Step 4 Now when we make any HTTP request, the user’s token will be attached automatically. Our TokenInterceptor was added to the HTTP Interceptors array by making the existing HTTP_Interceptors array use our new class. Now the application-scoped HTTP Interceptors service will use our new class, and the Authorization Header with our Bearer Token will be added to every HTTP Request. 15