okta / okta-oidc-js

okta-oidc-js
https://github.com/okta/okta-oidc-js
Other
395 stars 232 forks source link

OktaAuthService loginRedirect() not work since last 2.2.0 update #886

Open niskah-energies opened 4 years ago

niskah-energies commented 4 years ago

I'm submitting this issue for the package(s):

I'm submitting a:

Current behavior

AuthService login() function don't do anything and no errors

Expected behavior

trying to login with OKTA portal

Minimal reproduction of the problem with instructions


import { OktaAuthService } from '@okta/okta-angular';

const oktaConfig = {
  issuer: 'https://xxxxxxx.okta.com/oauth2/default',
  redirectUri: window.location.origin + '/implicit/callback',
  clientId: 'xxxxxxxx',
  scopes: ['openid', 'profile', 'email', 'offline_access'],
  pkce: true,
  isAuthenticated: async function(authService: OktaAuthService) { 
    const accessToken = await authService.getAccessToken();
    const idToken = await authService.getIdToken();
    return !!(accessToken && idToken);
  }
};

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  user : BehaviorSubject<User>  = new BehaviorSubject<User>(ANONYMOUS_USER);
  auth_state: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
  access_token: BehaviorSubject<string> = new BehaviorSubject<string>(null);

  constructor(public oktaAuth: OktaAuthService) {
    // get authentication state for immediate use
    this.oktaAuth.isAuthenticated().then(result => {
      this.auth_state.next(result);
    });

    // subscribe to authentication state changes
    this.oktaAuth.$authenticationState.subscribe(
      (isAuthenticated: boolean)  => this.auth_state.next(isAuthenticated)
    );

    // get user claims
    this.oktaAuth.getUser().then( result => {
      const userSubject = <User>{
        name: result.name,
        given_name: result.given_name,
        family_name: result.family_name,
        email: result.email,
        groups: result.groups
      };

      // get access token
      this.oktaAuth.getAccessToken().then(result => {
        this.access_token.next(result);
        console.log('AuthService:: update access token:' + result)
        localStorage.setItem('access_token', result);
      });

      //localStorage.setItem('user', JSON.stringify(this.user));
      this.user.next(userSubject);
    });

   }

  isAuthenticated() : Observable<boolean> {
    return this.auth_state.asObservable();
  }

  getUser() : Observable<User> {
    return this.user.asObservable();
  }

  // getAccessToken() : string {
  //   return localStorage.getItem('access_token');
  // }

  getAccessToken() : Promise<string> {
    return this.oktaAuth.getAccessToken();
  }

  getStoredAccessToken() : string {
    return localStorage.getItem('access_token');
  }

  login() {
   console.log('trying to connect...')
    this.oktaAuth.loginRedirect();
  }

  logout() {
    this.oktaAuth.logout('/');
  }
}

Extra information about the use case/user story you are trying to implement

Environment

shuowu commented 4 years ago

@niskah-energies Looks like you are missing the CallbackComponent to parse tokens from the redirect URL, can you try the okta angular sample to see if you still can reproduce the issue?

P.S. you may need to upgrade the version of @okta/okta-angular in the sample.

niskah-energies commented 4 years ago

Hi @shuowu, thank you for your reply. I'm using OktaAuthComponent, everything works before I update package.

When I'm trying to call /login route, I just have a blank page with no errors, before package update it redirects to Okta portal, but now there is no redirection. My route file:


import { OKTA_CONFIG, OktaAuthModule, OktaAuthGuard, OktaAuthService, OktaLoginRedirectComponent, OktaCallbackComponent } from '@okta/okta-angular';

...

const oktaConfig = {
  issuer: 'https://dev-xxxxx.okta.com/oauth2/default',
  redirectUri: window.location.origin + '/implicit/callback',
  clientId: 'xxxxx',
  scopes: ['openid', 'profile', 'email', 'offline_access'],
  pkce: true
  /*isAuthenticated: async function(authService: OktaAuthService) { // https://github.com/okta/okta-oidc-js/issues/460 - https://github.com/okta/okta-oidc-js/tree/master/packages/okta-angular
    const accessToken = await authService.getAccessToken();
    const idToken = await authService.getIdToken();
    return !!(accessToken && idToken);
  }*/
};

{ 
        path: '', 
        component: LandingLayoutComponent,
        children: [
          { path: '', component: LandingComponent, pathMatch: 'full'}
          //{ path: 'landing', component: LandingComponent }
        ]
  },
  {
    path: 'login',
    component: OktaLoginRedirectComponent
  },

...

  {
    path: 'implicit/callback',
    component: OktaCallbackComponent
  },
  { path: '**', redirectTo: '' }
];

@NgModule({
  declarations: [
    HomeComponent
  ],
  imports: [
    CommonModule,
    HttpClientModule,
    OktaAuthModule,
    RouterModule.forRoot(routes)
  ],
  providers: [
    { provide: OKTA_CONFIG, useValue: oktaConfig/*, multi:false*/ },
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
  ],
  exports: [RouterModule]
})
export class AuthRoutingModule { }
shuowu commented 4 years ago

@niskah-energies By glancing at the code, I don't see the cause of the issue.

Some suggestions:

  1. if you are developing a SPA app, you probably don't need offline_access in scopes
  2. you probably can take a closer look at HttpInterceptor
  3. blank page with no errors probably means there is an error but is being caught and suppressed by angular.

If you can reach out to our support team at developers@okta.com you can share details of your configuration and they can help us find out what is happening.

niskah-energies commented 4 years ago

I'm trying without HttpInterceptor ut it's the same, maybe problem leaves in OktaLoginRedirectComponent