Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Adding support for Authorization Code Flow with PKCE
  • Loading branch information
Robinyo committed Jul 21, 2019
1 parent b51f873 commit 0d3d8d9
Show file tree
Hide file tree
Showing 22 changed files with 514 additions and 344 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -45,3 +45,5 @@ Thumbs.db
/.firebase

TODO.txt

/pkce-demo
7 changes: 7 additions & 0 deletions out.txt
@@ -0,0 +1,7 @@
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "eyJraWQiOiJCMHcxTjVtU2FUM0RkS3ZXVHd6MnYyRk5XT3JMbGJ1elVJbElJVERHT19vIiwiYWxnIjoiUlMyNTYifQ.eyJ2ZXIiOjEsImp0aSI6IkFULmp0N3huZTJhNFd2Xzh0ZUtWUUZ5cGJvaS0zYjhHbW54d2lzZlczVmNvNmciLCJpc3MiOiJodHRwczovL2Rldi0zMzU0Njcub2t0YS5jb20vb2F1dGgyL2RlZmF1bHQiLCJhdWQiOiJhcGk6Ly9kZWZhdWx0IiwiaWF0IjoxNTYzNjkxNzgyLCJleHAiOjE1NjM2OTUzODIsImNpZCI6IjBvYXRnYThlYkE0SWtHZzVVMzU2IiwidWlkIjoiMDB1dGdiN2hqQ2szNkVKMlMzNTYiLCJzY3AiOlsib3BlbmlkIiwiZW1haWwiLCJncm91cHMiLCJwcm9maWxlIiwiYWRkcmVzcyIsInBob25lIl0sInN1YiI6InJvYi5mZXJndXNvbkByb2JmZXJndXNvbi5vcmciLCJncm91cHMiOlsiRXZlcnlvbmUiLCJVc2VyIiwiQWRtaW5pc3RyYXRvciJdfQ.gbQJRhYuZJZJ53EWZ1wJDExt5h8tVdpU3FPw2V_oV3uFGyWSI9QlGNDsK7kl2erRbJJL811NFxEn14sG1LYicZsizYZf2ykuLtFSmI-94fz-uAF4XP8NzXWP2Kp8e5SGxjWUSR_q-v84o9YV5xUK6YHMAhRCZHpxttVqV6X1j78HVNTgs7q-QsRFZP1tcnI0joNjn8SIS9BKhQXC7HqLMYdpeHvcSI66GwasjGyKLSiMZHgd47uvmbT7lYfFtU0OEwEdIMYmOwQJlYVbJj1iaMcQjPxXHWps2Kjdt2kr9px9ZhLt09L3v_O94qUPgDtoTiLJos9XjyfZ0RZofpOOoQ",
"scope": "openid email groups profile address phone",
"id_token": "eyJraWQiOiJCMHcxTjVtU2FUM0RkS3ZXVHd6MnYyRk5XT3JMbGJ1elVJbElJVERHT19vIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMHV0Z2I3aGpDazM2RUoyUzM1NiIsIm5hbWUiOiJSb2IgRmVyZ3Vzb24iLCJlbWFpbCI6InJvYi5mZXJndXNvbkByb2JmZXJndXNvbi5vcmciLCJ2ZXIiOjEsImlzcyI6Imh0dHBzOi8vZGV2LTMzNTQ2Ny5va3RhLmNvbS9vYXV0aDIvZGVmYXVsdCIsImF1ZCI6IjBvYXRnYThlYkE0SWtHZzVVMzU2IiwiaWF0IjoxNTYzNjkxNzgzLCJleHAiOjE1NjM2OTUzODMsImp0aSI6IklELlJieGtGSHJxcTZtX1FNRTBfaUs0dTZPTUZIN181TldsOTJMZWE2S0M2NzAiLCJhbXIiOlsicHdkIl0sImlkcCI6IjAwb3RnYjdla1ZqZnEzSGtLMzU2IiwicHJlZmVycmVkX3VzZXJuYW1lIjoicm9iLmZlcmd1c29uQHJvYmZlcmd1c29uLm9yZyIsImF1dGhfdGltZSI6MTU2MzY5MTc3OCwiYXRfaGFzaCI6IlltX3RIT1Q0TzlLcjVkbnJqWTFkYlEifQ.cW-b2dlJ6uVLc4h52uO-cVUnAJ2kODRn4Oh1gbTxWKDYWiX3LDa4EDdrqXQ4WjzVZalUhPYtbVmZN47zgPSqvgzLKCc-TIogpfFtL-d-RATdFTnT-M4z9UCr98xNEAFeEmGSlISDju63ucPIkBHlvb0MHwDmQyOS_Jn4BWXRulOLR5UHvY6BlRqekQXValfHUW2X1HC_BNLsJ-UMaxf4ErKDXrOHwE3vVbWK95xCLhOJRtqIqUd0zxUYsEmLJ9GWJm6vWaLBPvj6crg6HeUOOz0mLumS-iYoUS4JDyLXdFw8m44qCmfi69sLSIAOYD59X7HHlQRopwxlcLuHkV0gqg"
}
16 changes: 2 additions & 14 deletions projects/auth-okta/src/lib/auth-okta.module.ts
Expand Up @@ -8,8 +8,6 @@ import { AuthOktaConfig } from './models/models';
import { AuthOktaConfigService } from './services/config.service';

import { LoginComponent } from './components/login/login.component';
import { CallbackComponent } from './components/callback/callback.component';

//
// Auth lib
//
Expand All @@ -20,7 +18,6 @@ import { AuthModule } from 'auth';
// Utils lib
//

// import { UtilsModule, LoggerService, ConsoleLoggerService } from 'utils';
import { UtilsModule, LoggerService, loggerProviders } from 'utils';

//
Expand All @@ -38,16 +35,16 @@ import { LibRoutingModule } from './lib-routing.module';

LibRoutingModule // https://angular.io/guide/router#routing-module-order
],
declarations: [ CallbackComponent, LoginComponent ],
declarations: [ LoginComponent ],
providers: [
// { provide: LoggerService, useClass: ConsoleLoggerService }
loggerProviders
],
exports: []
})
export class AuthOktaModule {

constructor(private logger: LoggerService) {

this.logger.info('Auth Okta Module initialised');
}

Expand All @@ -64,12 +61,3 @@ export class AuthOktaModule {
}

}

// https://github.com/okta/samples-js-angular/blob/master/okta-hosted-login/util/default-config.ts

/*
// OktaAuthModule.initAuth(oidc),
// { provide: OKTA_CONFIG, useValue: oidc }
*/

This file was deleted.

This file was deleted.

Expand Up @@ -20,7 +20,8 @@ export class LoginComponent implements AfterViewInit, OnInit {

this.logger.info('LoginComponent: ngAfterViewInit()');

this.authService.auth.loginRedirect();
// this.authService.auth.loginRedirect();
this.authService.auth.authorizationCodeRedirect();
}

}
Expand Down
8 changes: 4 additions & 4 deletions projects/auth-okta/src/lib/lib-routing.module.ts
Expand Up @@ -2,10 +2,10 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// import { OktaCallbackComponent } from '@okta/okta-angular';
import { OktaCallbackComponent } from 'okta-angular';
import { OktaAuthorizationCodeCallbackComponent } from 'okta-angular';
import { OktaImplicitCallbackComponent } from 'okta-angular';

import { LoginComponent } from './components/login/login.component';
import { CallbackComponent } from './components/callback/callback.component';

const routes: Routes = [

Expand All @@ -16,12 +16,12 @@ const routes: Routes = [

{
path: 'authorization-code/callback',
component: CallbackComponent
component: OktaAuthorizationCodeCallbackComponent
},

{
path: 'implicit/callback',
component: OktaCallbackComponent
component: OktaImplicitCallbackComponent
}

];
Expand Down
Expand Up @@ -38,7 +38,7 @@ export abstract class CollectionService {

this.httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa(token)
}),
params: null
Expand Down
@@ -0,0 +1,36 @@
import { Component, OnInit } from '@angular/core';
// import { ActivatedRoute } from '@angular/router';

import { OktaAuthService } from '../../services/auth/okta-auth.service';

@Component({ template: `` })
export class OktaAuthorizationCodeCallbackComponent implements OnInit {

constructor(private authService: OktaAuthService) {
}

public ngOnInit() {

this.authService.handleAuthorizationCodeFlow();
}

}

// https://stackoverflow.com/questions/38255939/how-to-handle-hash-fragments-from-oauth-redirect-urls-in-angular2-rc3-routing/

// OIDC Authorization Code Flow (OAuth2 Authorization Code Grant)

/*
constructor(private route: ActivatedRoute,
private authService: OktaAuthService) {
}
const code = this.route.snapshot.paramMap.get('code');
const state = this.route.snapshot.paramMap.get('state');
console.log('code: ' + code + ' state: ' + state);
this.authService.handleAuthorizationCodeFlow(code, state);
*/
Expand Up @@ -12,14 +12,14 @@

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

import { OktaAuthService } from '../services/okta-auth.service';
import { OktaAuthService } from '../../services/auth/okta-auth.service';

@Component({ template: `` })
export class OktaImplicitCallbackComponent {

@Component({template: `` })
export class OktaCallbackComponent {
constructor(private okta: OktaAuthService) {
/**
* Handles the response from Okta and parses tokens.
*/
okta.handleAuthentication();

okta.handleImplicitFlow();
}

}
Expand Up @@ -12,11 +12,13 @@

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

import { OktaAuthService } from '../services/okta-auth.service';
import { OktaAuthService } from '../../services/auth/okta-auth.service';

@Component({ template: `` })
export class OktaLoginRedirectComponent {

constructor(private okta: OktaAuthService) {
okta.loginRedirect();
}

}
11 changes: 7 additions & 4 deletions projects/okta-angular/src/lib/create-okta-service.ts
Expand Up @@ -10,10 +10,13 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { OktaConfig } from './models/okta.config';
// import { DOCUMENT } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { OktaAuthService } from './services/okta-auth.service';

export function createOktaService(config: OktaConfig, router: Router) {
return new OktaAuthService(config, router);
import { OktaAuthService } from './services/auth/okta-auth.service';
import { OktaConfig } from './models/okta.config';

export function createOktaService(document: any, config: OktaConfig, http: HttpClient, router: Router) {
return new OktaAuthService(document, config, http, router);
}
Expand Up @@ -18,8 +18,8 @@ import {
Router
} from '@angular/router';

import { OktaAuthService } from '../services/okta-auth.service';
import { AuthRequiredFunction } from '../models/auth-required-function';
import { OktaAuthService } from '../../services/auth/okta-auth.service';
import { AuthRequiredFunction } from '../../models/auth-required-function';

@Injectable()
export class OktaAuthGuard implements CanActivate {
Expand All @@ -28,8 +28,6 @@ export class OktaAuthGuard implements CanActivate {
/**
* Gateway for protected route. Returns true if there is a valid accessToken,
* otherwise it will cache the route and start the login flow.
* @param route
* @param state
*/
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (await this.oktaAuth.isAuthenticated()) {
Expand Down
Expand Up @@ -12,6 +12,6 @@

import { Router } from '@angular/router';

import { OktaAuthService } from '../services/okta-auth.service';
import { OktaAuthService } from '../services/auth/okta-auth.service';

export type AuthRequiredFunction = (oktaAuth: OktaAuthService, router: Router) => void;
21 changes: 20 additions & 1 deletion projects/okta-angular/src/lib/models/okta.config.ts
Expand Up @@ -14,6 +14,25 @@ import { InjectionToken } from '@angular/core';

import { AuthRequiredFunction } from './auth-required-function';

export interface OktaConfig {
clientId: string;
code_challenge: string;
code_challenge_method: string;
issuer: string;
onAuthRequired?: AuthRequiredFunction;
redirectUri: string;
responseType: string;
scope: string;
state: string;
testing: {
disableHttpsCheck: boolean
};
}

export const OKTA_CONFIG = new InjectionToken<OktaConfig>('okta.config.angular');

/*
export interface TestingObject {
disableHttpsCheck: boolean;
}
Expand All @@ -28,4 +47,4 @@ export interface OktaConfig {
testing?: TestingObject;
}
export const OKTA_CONFIG = new InjectionToken<OktaConfig>('okta.config.angular');
*/
23 changes: 16 additions & 7 deletions projects/okta-angular/src/lib/okta-auth.module.ts
Expand Up @@ -10,24 +10,29 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { DOCUMENT } from '@angular/common';
import { ModuleWithProviders, NgModule } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';

import { OktaCallbackComponent } from './components/callback.component';
import { OktaLoginRedirectComponent } from './components/login-redirect.component';
import { OktaAuthorizationCodeCallbackComponent } from './components/authorization-code/authorization-code.component';
import { OktaImplicitCallbackComponent } from './components/implicit-callback/implicit-callback.component';
import { OktaLoginRedirectComponent } from './components/login-redirect/login-redirect.component';

import { OktaAuthService } from './services/okta-auth.service';
import { OktaAuthGuard } from './guards/okta-auth.guard';
import { OktaAuthService } from './services/auth/okta-auth.service';
import { OktaAuthGuard } from './guards/auth/okta-auth.guard';
import { OktaConfig, OKTA_CONFIG } from './models/okta.config';
import { createOktaService } from './create-okta-service';
import { Router } from '@angular/router';

@NgModule({
declarations: [
OktaCallbackComponent,
OktaAuthorizationCodeCallbackComponent,
OktaImplicitCallbackComponent,
OktaLoginRedirectComponent
],
exports: [
OktaCallbackComponent,
OktaAuthorizationCodeCallbackComponent,
OktaImplicitCallbackComponent,
OktaLoginRedirectComponent
],
providers: [
Expand All @@ -36,13 +41,16 @@ import { Router } from '@angular/router';
provide: OktaAuthService,
useFactory: createOktaService,
deps: [
DOCUMENT,
OKTA_CONFIG,
HttpClient,
Router
]
}
]
})
export class OktaAuthModule {

// Deprecated. Your app should provide OKTA_CONFIG directly
static initAuth(config: OktaConfig): ModuleWithProviders {
return {
Expand All @@ -53,4 +61,5 @@ export class OktaAuthModule {
]
};
}

}

0 comments on commit 0d3d8d9

Please sign in to comment.