Learn About Authentication Between Node.js Applications and Oracle Identity Cloud Service
You’re ready to learn about authentication between Node.js web applications and Oracle Identity Cloud Service. This includes understanding the following:
-
The three-legged authentication flow that Oracle Identity Cloud Service supports for the Node.js SDK
-
Use cases for using an SDK with a Node.js application to authenticate with Oracle Identity Cloud Service
-
Methods and functions of the Node.js SDK
Learn About Three-Legged Authentication Flows
Oracle Identity Cloud Service supports the three-legged authentication flow for the Node.js SDK. In this flow, users interact directly with Oracle Identity Cloud Service. After a user signs in, Oracle Identity Cloud Service issues an authorization code that the SDK exchanges for a user access token. The Node.js web application uses this access token to grant users access to the protected resources in the application. The three-legged flow uses the authorization code grant type.
For increased security, Oracle recommends that you use the three-legged flow to integrate your Node.js web applications with Oracle Identity Cloud Service for authentication. By using the authorization code grant type, you can also access other applications that are protected by Oracle Identity Cloud Service without having to reauthenticate.
Learn About the Primary Use Cases for Using an SDK with a Node.js Application
The Node.js web application implements two use cases: one for authenticating users, and the other for accessing detailed information about the logged-in user.
The following data flow diagrams illustrate the flow of events, calls, and responses between the web browser, the web application, and Oracle Identity Cloud Service for each use case.
Use Case #1: Authenticate a User
The data flow happens this way:
-
The user requests a protected resource.
-
The authentication module uses the SDK to generate a request-authorization-code URL for Oracle Identity Cloud Service and send this URL as a redirect response to the web browser.
-
The web browser calls the URL.
-
The Oracle Identity Cloud Service Sign In page appears.
-
The user submits their Oracle Identity Cloud Service sign-in credentials.
-
After the user signs in, Oracle Identity Cloud Service creates a session for the user and issues an authorization code.
-
The web application makes a back-end (or server-to-server) call to exchange the authorization code for a user access token.
-
Oracle Identity Cloud Service issues the access token.
-
A session is established, and the user is redirected to the Home page.
-
The Home page of the web application appears.
Use Case #2: Get Details About the User
The data flow happens this way:
-
The user requests the
/myProfile
resource. -
The web application calls Oracle Identity Cloud Service using the SDK, which uses the access token that’s stored in the user session as a parameter.
-
The user's details are sent to the web application as a JSON object.
-
The My Profile page renders the JSON object as HTML content.
Learn About Methods and Functions
The Node.js SDK is a Node.js passport strategy that you add to your Node.js modules
folder. This SDK is also based on Node.js promises. All third-party dependencies that the Node.js SDK needs are defined in the SDK’s package.json
file. You need to use at least this set of modules in your Node.js web application.
"dependencies": {
"async": "^2.1.2",
"bunyan": "^1.8.5",
"cache-manager": "^2.2.0",
"json-web-token": "^2.1.3",
"jsonwebtoken": "^7.1.9",
"jwk-to-pem": "^1.2.6",
"jws": "^3.1.4",
"lru": "^3.1.0",
"passport": "^0.3.2",
"promise": "^7.1.1",
"querystring": "^0.2.0",
"request": "^2.79.0",
"rsa-pem-to-jwk": "^1.1.3",
"util": "^0.10.3"
},
A Node.js web application was developed using the Node.js express
and express-handlebars
modules, which implements URL routes in the form of an app.get()
function for each URL.
The Node.js SDK requires a JSON variable that’s loaded with Oracle Identity Cloud Service connection information. The Node.js web application uses the ids
variable to store this information:
var ids = {
oracle: {
"ClientId": '123456789abcdefghij',
"ClientSecret": 'abcde-12345-zyxvu-98765-qwerty',
"ClientTenant": 'idcs-abcd1234',
"IDCSHost": 'https://%tenant%.identity.oraclecloud.com',
"AudienceServiceUrl" : 'https://idcs-abcd1234.identity.oraclecloud.com',
"TokenIssuer": 'https://identity.oraclecloud.com/',
"scope": 'urn:opc:idm:t.user.me openid',
"logoutSufix": '/oauth2/v1/userlogout',
"redirectURL": 'http://localhost:3000/callback'
}
};
module.exports = ids;
Below is a brief explanation of each required attribute for this SDK:
Name | Description |
---|---|
ClientId |
The value of the Client ID that’s generated after you register the Node.js web application in the Identity Cloud Service console. |
ClientSecret |
The value of the Client Secret that’s generated after you register the Node.js web application in the Identity Cloud Service console. |
ClientTenant |
The domain prefix of your Oracle Identity Cloud Service instance. This prefix is usually similar to idcs-abcd1234 .
|
IDCSHost |
The domain suffix of your Oracle Identity Cloud Service instance. At runtime, the %tenant% placeholder is replaced by the value of the ClientTenant attribute. |
AudienceServiceUrl |
The fully-qualified domain name URL of your Oracle Identity Cloud Service instance. |
TokenIssuer |
For this attribute, Oracle recommends that you keep the value https://identity.oraclecloud.com/ .
|
scope |
The scope controls the data that the application can access or process on behalf of the Oracle Identity Cloud Service user. If the application uses the SDK to authenticate a user, then the scope is |
The application uses both the logoutSufix
and redirectURL
attributes. The SDK doesn’t require them.
The Node.js application implements the /oauth/oracle
URL route. When a user decides to authenticate with Oracle Identity Cloud Service, the web browser makes a request to this URL. This route uses the SDK to generate Oracle Identity Cloud Service's authorization URL.
//Loading the configurations
var auth = require('./auth.js');
//Route for /oauth/oracle
app.get("/auth/oracle", function(req, res){
//Authentication Manager loaded with the configurations.
am = new IdcsAuthenticationManager(auth.oracle);
//Using Authentication Manager to generate the Authorization Code URL, passing the
//application's callback URL as parameter, along with code value and code parameter.
am.getAuthorizationCodeUrl(auth.oracle.redirectURL, auth.oracle.scope, "1234", "code")
.then(function(authZurl){
//Redirecting the browser to the Oracle Identity Cloud Service Authorization URL.
res.redirect(authZurl);
}).catch(function(err){
res.end(err);
})
});
This function loads the JSON parameters to a variable, initializes an authentication manager, and uses the IdcsAuthenticationManager.getAuthorizationCodeUrl()
function of the Node.js SDK to generate the authorization code URL. This function uses promise to either redirect the user's web browser when the authorization code URL is generated or to render an error in the browser.
The following parameters are used to generate the authorization code URL:
Name | Description |
---|---|
auth.oracle.redirectURL |
After a user signs in, Oracle Identity Cloud Service redirects the user’s web browser to this URL. This URL must match the one you’ll configure for the trusted application in the Identity Cloud Service console. See Register the Node.js Application for more information about specifying a redirect URL for the Node.js web application. |
auth.oracle.scope |
The OAuth or OpenID Connect scope of authentication. This application requires only openid authentication.
|
state |
The OAuth protocol defines this parameter. The sample Node.js web application uses this code to check whether communication can be established to Oracle Identity Cloud Service. For this example, the value for this parameter is 1234 .
|
response_type |
The parameter required by the authorization code grant type. For this example, the value for this parameter is code .
|
After the user signs in, Oracle Identity Cloud Service redirects the user’s web browser to a callback URL, which the developer must implement. The Node.js web application uses the /callback
route to handle this request.
//Route for /callback
app.get("/callback", function(req,res){
//Authentication Manager loaded with the configurations.
var am = new IdcsAuthenticationManager(auth.oracle);
//Getting the authorization code from the "code" parameter
var authZcode = req.query.code;
//Using the Authentication Manager to exchange the Authorization Code to an Access Token.
am.authorizationCode(authZcode)
.then(function(result){
//Getting the Access Token Value.
res.cookie(config.IDCS_COOKIE_NAME, result.access_token);
res.redirect('/auth.html');
}).catch(function(err){
res.end(err);
})
});
The Node.js application uses the authorization code to request an access token. The access token is stored as a cookie, which is then sent to the web browser for future use.
The IdcsAuthenticationManager.authorizationCode()
function of the Node.js SDK also uses promise (a then-catch statement) to set the access token as a cookie, and to redirect the browser to the /auth.html
page.
The Node.js SDK is based on the Node.js passport framework. Therefore, you have to forward the access token as a header variable to the /auth
URL handler, and use the passport.authenticate()
method with the Oracle Identity Cloud Service Strategy Name as a parameter:
//Uses passport to create a User Session in Node.js.
//Passport sets a user attribute in the request as a json object.
app.get('/auth', passport.authenticate(config.IDCS_STRATEGY_NAME, {}), function(req, res) {
res.redirect('/home');
});
After the passport.authenticate()
method creates the application's session, the function redirects the user’s web browser to a protected URL in the /home
application. In addition to /home
, the Node.js web application has three other protected URLs: /appDetails
, /userInfo
, and /myProfile
.
Each protected URL needs to check whether the user's session was created previously. The following function is used by each app.get()
function for these URLs.
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login')
}
The Node.js application handles the /myProfile
route and gets information set in the session by the passport.authenticate()
method, as follows:
app.get("/myProfile", ensureAuthenticated, function(req,res){
//User Manager loaded with the configurations
var um = new IdcsUserManager(auth.oracle);
//Using the user id in the request attribute to render the user json in the screen.
um.getUser(req.user.id)
.then(function(user){
res.render('myProfile', {
layout: 'privateLayout',
title: 'My Profile',
user: req.user,
userInfo: JSON.stringify(user, null, 2)
});
}).catch(function(err1){
res.end(err1);
})
});
After initializing the UserManager
object, the /myProfile
route's handler uses the SDK’s IdcsUserManager.getUser()
function to get a JSON object that represents the user profile. The application sends the JSON object to the myProfile.handlebars
file for rendering in the web browser.
To sign the user out from single sign-on between the application and Oracle Identity Cloud Service, the Node.js web application implements the /logout
route, as follows:
app.get('/logout', function(req, res){
req.logout();
res.clearCookie();
res.redirect(auth.oracle.IDCSHost + auth.oracle.logoutSufix);
});
This route invalidates the application’s session, removes any cookies set previously, and then redirects the user’s web browser to Oracle Identity Cloud Service's OAuth log out URL. This URL is set up in the JSON configuration object.