Merge pull request #19 from jenmalloy/securing-apps_RHSSO-639

fixed RHSSO-639
This commit is contained in:
Jen Malloy 2017-03-02 17:05:43 -05:00 committed by GitHub
commit 21710f9e41
2 changed files with 41 additions and 24 deletions

View file

@ -18,7 +18,7 @@ is selected for `Access Type`.
You also need to configure valid redirect URIs and valid web origins. Be as specific as possible as failing to do so may result in a security vulnerability. You also need to configure valid redirect URIs and valid web origins. Be as specific as possible as failing to do so may result in a security vulnerability.
Once the client is created click on the `Installation` tab select `Keycloak OIDC JSON` for `Format Option` then click on `Download`. The downloaded Once the client is created click on the `Installation` tab select `Keycloak OIDC JSON` for `Format Option` then click `Download`. The downloaded
`keycloak.json` file should be hosted on your web server at the same location as your HTML pages. `keycloak.json` file should be hosted on your web server at the same location as your HTML pages.
Alternatively, you can skip the configuration file and manually configure the adapter. Alternatively, you can skip the configuration file and manually configure the adapter.
@ -112,7 +112,7 @@ keycloak.updateToken(30).success(function() {
); );
---- ----
==== Session status iframe ==== Session Status iframe
By default, the JavaScript adapter creates a hidden iframe that is used to detect if a Single-Sign Out has occurred. By default, the JavaScript adapter creates a hidden iframe that is used to detect if a Single-Sign Out has occurred.
This does not require any network traffic, instead the status is retrieved by looking at a special status cookie. This does not require any network traffic, instead the status is retrieved by looking at a special status cookie.
@ -164,23 +164,22 @@ For the Hybrid flow, you need to pass the parameter `flow` with value `hybrid` t
keycloak.init({ flow: 'hybrid' }) keycloak.init({ flow: 'hybrid' })
---- ----
==== Older browsers ==== Earlier Browsers
The JavaScript adapter depends on Base64 (window.btoa and window.atob) and HTML5 History API. The JavaScript adapter depends on Base64 (window.btoa and window.atob) and HTML5 History API.
If you need to support browsers that don't have these available (for example IE9) you need to add polyfillers. If you need to support browsers that do not have these available (for example, IE9) you need to add polyfillers.
Example polyfill libraries: Example polyfill libraries:
* https://github.com/davidchambers/Base64.js * https://github.com/davidchambers/Base64.js
* https://github.com/devote/HTML5-History-API * https://github.com/devote/HTML5-History-API
==== JavaScript Adapter reference ==== JavaScript Adapter Reference
===== Constructor ===== Constructor
[source] [source,javascript]
---- ----
new Keycloak(); new Keycloak();
new Keycloak('http://localhost/keycloak.json'); new Keycloak('http://localhost/keycloak.json');
new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp' }); new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp' });
@ -357,7 +356,7 @@ Invoking this results in onAuthLogout callback listener being invoked.
The adapter supports setting callback listeners for certain events. The adapter supports setting callback listeners for certain events.
For example: For example:
[source] [source,javascript]
---- ----
keycloak.onAuthSuccess = function() { alert('authenticated'); } keycloak.onAuthSuccess = function() { alert('authenticated'); }
---- ----
@ -370,4 +369,4 @@ The available events are:
* onAuthRefreshSuccess - Called when the token is refreshed. * onAuthRefreshSuccess - Called when the token is refreshed.
* onAuthRefreshError - Called if there was an error while trying to refresh the token. * onAuthRefreshError - Called if there was an error while trying to refresh the token.
* onAuthLogout - Called if the user is logged out (will only be called if the session status iframe is enabled, or in Cordova mode). * onAuthLogout - Called if the user is logged out (will only be called if the session status iframe is enabled, or in Cordova mode).
* onTokenExpired - Called when the access token is expired. If a refresh token is available the token can be refreshed with updateToken, or in cases where it's not (ie. with implicit flow) you can redirect to login screen to obtain a new access token. * onTokenExpired - Called when the access token is expired. If a refresh token is available the token can be refreshed with updateToken, or in cases where it is not (that is, with implicit flow) you can redirect to login screen to obtain a new access token.

View file

@ -1,16 +1,16 @@
[[_nodejs_adapter]] [[_nodejs_adapter]]
=== Node.js Adapter === Node.js Adapter
{{book.project.name}} provides a Node.js adapter built on top of https://github.com/senchalabs/connect[Connect] to protect server side JavaScript apps — the goal was to be flexible enough to integrate with frameworks like https://expressjs.com/[Express.js]. {{book.project.name}} provides a Node.js adapter built on top of https://github.com/senchalabs/connect[Connect] to protect server-side JavaScript apps — the goal was to be flexible enough to integrate with frameworks like https://expressjs.com/[Express.js].
{% if book.community %} {% if book.community %}
The library can be downloaded directly from https://www.npmjs.com/package/keycloak-connect[ {{book.project.name}} organization] and the source is available at The library can be downloaded directly from https://www.npmjs.com/package/keycloak-connect[ {{book.project.name}} organization] and the source is available at
https://github.com/keycloak/keycloak-nodejs-connect[GitHub]. https://github.com/keycloak/keycloak-nodejs-connect[GitHub].
{% endif %} {% endif %}
To use the Node.js adapter, first you must create a client for your application in the {{book.project.name}} Administration Console. The adapter supports public, confidential and bearer-only access type. Which one to choose depends on the use-case scenario. To use the Node.js adapter, first you must create a client for your application in the {{book.project.name}} Administration Console. The adapter supports public, confidential, and bearer-only access type. Which one to choose depends on the use-case scenario.
Once the client is created click on the `Installation` tab select `{{book.project.name}} OIDC JSON` for `Format Option` then click on `Download`. The downloaded `keycloak.json` file should be at the root folder of your project. Once the client is created click the `Installation` tab, select `{{book.project.name}} OIDC JSON` for `Format Option`, and then click `Download`. The downloaded `keycloak.json` file should be at the root folder of your project.
==== Installation ==== Installation
@ -49,8 +49,11 @@ The `Keycloak` class provides a central point for configuration
and integration with your application. The simplest creation and integration with your application. The simplest creation
involves no arguments. involves no arguments.
[source,javascript]
----
var Keycloak = require('keycloak-connect'); var Keycloak = require('keycloak-connect');
var keycloak = new Keycloak(); var keycloak = new Keycloak();
----
By default, this will locate a file named `keycloak.json` alongside By default, this will locate a file named `keycloak.json` alongside
the main executable of your application to initialize keycloak-specific the main executable of your application to initialize keycloak-specific
@ -62,51 +65,63 @@ being used.
Configuring a web session store:: Configuring a web session store::
If you wish to use web sessions to manage If you want to use web sessions to manage
server-side state for authentication, you will need to initialize the server-side state for authentication, you need to initialize the
`Keycloak(...)` with at least a `store` parameter, passing in the actual `Keycloak(...)` with at least a `store` parameter, passing in the actual
session store that `express-session` is using. session store that `express-session` is using.
[source,javascript]
----
var session = require('express-session'); var session = require('express-session');
var memoryStore = new session.MemoryStore(); var memoryStore = new session.MemoryStore();
var keycloak = new Keycloak({ store: memoryStore }); var keycloak = new Keycloak({ store: memoryStore });
----
Passing a custom scope value:: Passing a custom scope value::
By default, the scope value `openid` will be passed as query parameter to {{book.project.name}}'s login URL but you can add an additional custom value : By default, the scope value `openid` is passed as a query parameter to {{book.project.name}}'s login URL, but you can add an additional custom value:
[source,javascript]
var keycloak = new Keycloak({ scope: 'offline_access' }); var keycloak = new Keycloak({ scope: 'offline_access' });
==== Install middleware ==== Installing Middleware
Once instantiated, install the middleware into your connect-capable app: Once instantiated, install the middleware into your connect-capable app:
[source,javascript]
----
var app = express(); var app = express();
app.use( keycloak.middleware() ); app.use( keycloak.middleware() );
----
==== Protect resources ==== Protecting Resources
Simple authentication:: Simple authentication::
To enforce that an user must be authenticated before accessing a resource, To enforce that an user must be authenticated before accessing a resource,
simply use a no-argument version of `keycloak.protect()`: simply use a no-argument version of `keycloak.protect()`:
[source,javascript]
----
app.get( '/complain', keycloak.protect(), complaintHandler ); app.get( '/complain', keycloak.protect(), complaintHandler );
----
Role-based authorization:: Role-based authorization::
To secure a resource with an application role for the current app: To secure a resource with an application role for the current app:
[source,javascript]
----
app.get( '/special', keycloak.protect('special'), specialHandler ); app.get( '/special', keycloak.protect('special'), specialHandler );
----
To secure a resource with an application role for a *different* app: To secure a resource with an application role for a *different* app:
[source,javascript]
app.get( '/extra-special', keycloak.protect('other-app:special', extraSpecialHandler ); app.get( '/extra-special', keycloak.protect('other-app:special', extraSpecialHandler );
To secure a resource with a realm role: To secure a resource with a realm role:
[source,javascript]
app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler ); app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler );
Advanced authorization:: Advanced authorization::
@ -114,11 +129,14 @@ Advanced authorization::
To secure resources based on parts of the URL itself, assuming a role exists To secure resources based on parts of the URL itself, assuming a role exists
for each section: for each section:
[source,javascript]
----
function protectBySection(token, request) { function protectBySection(token, request) {
return token.hasRole( request.params.section ); return token.hasRole( request.params.section );
} }
app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler ); app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler );
----
==== Additional URLs ==== Additional URLs
@ -127,14 +145,14 @@ Explicit user-triggered logout::
By default, the middleware catches calls to `/logout` to send the user through a By default, the middleware catches calls to `/logout` to send the user through a
{{book.project.name}}-centric logout workflow. This can be changed by specifying a `logout` {{book.project.name}}-centric logout workflow. This can be changed by specifying a `logout`
configuration parameter to the `middleware()` call: configuration parameter to the `middleware()` call:
[source,javascript]
app.use( keycloak.middleware( { logout: '/logoff' } )); app.use( keycloak.middleware( { logout: '/logoff' } ));
{{book.project.name}} Admin Callbacks:: {{book.project.name}} Admin Callbacks::
Also, the middleware supports callbacks from the {{book.project.name}} console to logout a single Also, the middleware supports callbacks from the {{book.project.name}} console to log out a single
session or all sessions. By default, these type of admin callbacks occur relative session or all sessions. By default, these type of admin callbacks occur relative
to the root URL of `/` but can be changed by providing an `admin` parameter to the root URL of `/` but can be changed by providing an `admin` parameter
to the `middleware()` call: to the `middleware()` call:
[source,javascript]
app.use( keycloak.middleware( { admin: '/callbacks' } ); app.use( keycloak.middleware( { admin: '/callbacks' } );