@almaobservatory/alma-oidc-client
v1.13.10
Published
This is version **1.13.10** for Angular 13: added `publicURLs` optional config option, corrected README file.
Downloads
2,223
Keywords
Readme
The @almaobservatory/alma-oidc-client library
This is version 1.13.10 for Angular 13: added publicURLs
optional config option,
corrected README file.
This is an ALMA-specific OAuth2/OIDC client library based on angular-oauth2-oidc. This implementation is for the Keycloak Identity Provider as configured for ALMA.
The library's code is in OBOPS/npm/alma-oidc-client-lib/projects/alma-oidc-client.
An example client application for this library is available.
Development
The library was developed using the process described here.
NOTE If you don't follow that process precisely you'll end up in trouble: no shortcuts!
Should you need to develop this library at the same time
as the client application you
should use the same approach used by
the example application,
see the pull-lib
target of
Makefile there.
NOTE That may require a bit of juggling with npm install
before you
get it right.
Build
From the top level directory, OBOPS/npm/alma-oidc-client, launch make clean build
-- it will run npm install
and ng build
.
Publishing the library to NPM
New versions of the library may be published to NPM to make them available ALMA developers.
NOTE You cannot publish the same version twice. You'll need to update
the version
number in package.json before attempting to publish a library.
NOTE Remember to update the first paragraph fo this file!
Command make publish
will rebuild and publish the library to the NPM registry
Un-publishing the library from NPM
From the command line:
npm unpublish @almaobservatory/alma-oidc-client@<version>
where <version>
is something like 0.1.1
.
Usage in your client application
General notes
- Make sure your application does not interfere with Session Storage, as
angular-oauth2-oidc saves important information there. Specifically,
make sure you never call
window.sessionStorage.clear()
.
Update package.json
Add the following dependencies to src/main/angular/package.json:
"@almaobservatory/alma-oidc-client": "^1.11.0",
"angular-oauth2-oidc": "^8.0.0",
"angular-oauth2-oidc-jwks": "^9.0.0",
environment.ts
Edit src/main/angular/src/environments/environment.ts and its prod counterpart
adding the securedUrls
and oauthOidcClientID
fields.
export const environment = {
...
securedUrls: [ ... ],
oauthOidcClientID: 'oidc',
...
};
Field securedUrls
should
include an array of URL fragments (strings): they will be used to identify
which HTTP requests should carry an Authorization header with a Bearer
token.
The fragments should match all URLs configured on the server side
in the .antMatchers()
calls within
the WebSecurityConfigurerAdapter
, including all authenticated()
and
.hasAnyAuthority()
cases.
For instance, with the following antMatchers
:
.antMatchers( "/public/api/**" ).permitAll()
.antMatchers( "/admin/api/dr/**" ).hasAnyAuthority( "OBOPS/DRM", "OBOPS/ARCA" )
.antMatchers( "/service/api/**" ).authenticated()
one should set the securedUrls
field to:
securedUrls: ['admin','service']
See also
AlmaOidcAuthInterceptorConfig
.
NOTE
An case like .antMatchers( "/**" ).authenticated()
cannot be
mapped, and your antMatchers should always include an actual URL
fragment.
Obviously, .antMatchers( "/**" ).permitAll()
is fine, if risky.
app.module.ts
import { OAuthModule } from 'angular-oauth2-oidc';
import { environment } from '../environments/environment';
import { AlmaOidcModule } from "@almaobservatory/alma-oidc-client";
...
imports: [
...
OAuthModule.forRoot(),
AlmaOidcModule.forRoot( { securedURLs: environment.securedUrls } ),
]
app-routing.module.ts
RouterModule.forRoot()
: if you set property useHash
to true
make sure you also set initialNavigation
to false
,
see here.
NOTE As of Angular 11, the RouterModule
configuration should have initialNavigation
set to 'disabled'
instead of false
.
app.globals.ts
In this file, or similar location like environments/environment.ts, define the URL of our resource server,
up to and including the context path, and excluding anything beyond that.
For instance,
this.resourceServerURL = this.developmentMode ? 'http://localhost:10000/snoopi' : '/snoopi';
app.component.ts
Method AlmaOidcService.authenticateAndInit()
performs the
authentication sequence.
Parameters:
clientID: ID of the OIDC client, for instance 'oidc'
resourceServerURL: URL of our resource server, up to and including the context path, and excluding anything beyond that.
For instance, http://localhost:10000/clai
The method returns a promise that can be used to run initialization code
and navigate to the user's intended tab — navigation was suspended in
AppRoutingModule with initialNavigation: false
(or 'disabled'
,
in Angular 11+) — after
initialization completes successfully.
For instance:
import { AlmaOidcService } from '@almaobservatory/alma-oidc-client';
import { environment } from "../environments/environment";
import { Globals } from './app.globals';
import { Router } from '@angular/router';
...
constructor( ...,
private router: Router,
private almaOidcService: AlmaOidcService,
private globals: Globals ) { ... }
...
ngOnInit(): void {
...
// At the end of the authentication/initialization phase we need to navigate to
// the user's intended tab: we extract that from the URL they used to get here
// If none is found we provide a default tab
const navigateTo = window.location.hash.length === 0 ? '/default-tab' : window.location.hash.substr( 1 );
this.almaOidcService
.authenticateAndInit( environment.oauthOidcClientID, this.globals.resourceServerURL )
.then( () => this.router.navigate( [navigateTo] ))
.then( () => this.appService.startup() );
Other changes
Remove all calls to the
/login-check
,/do-logout
and/account
endpoints, and any related codeAfter successful authentication, some user information, including username, full name and email address, can be obtained from the OIDC tokens; there is no need to query the resource server for that.
InAlmaOidcService
seeuserIdentity
getter and the shortcut gettersusername
,fullname
,email
androles
.
For instance,this.globals.account = { name: this.almaOidcService.fullname, authorities: this.almaOidcService.roles };
To log out of the application and the OIDC server, use
AlmaOidcService.logout()