Problem description

In the first two blog posts , Yes NodeJS Express application Use MSAL + AAD Realize user login and obtain user information , obtain Authorization Information ( ID Token, Access Token).

  1. 【Azure Application service 】NodeJS Express + MSAL Application implementation AAD Integrated login and deployment in App Service Linux Implementation steps in the environment

  2. 【Azure Application service 】NodeJS Express + MSAL Application implementation AAD Log in and get AccessToken -- cca.acquireTokenByCode(tokenRequest)

In the current blog post , We will achieve the following objectives :

1) by NodeJS API Application configuration Bearer Token Verify components  passport and  passport-azure-ad

2) Implementations use idToken Verify and access API

Implementation steps

At the completion of Azure AD Register the application configuration in and according to the blog “ NodeJS Express + MSAL Application implementation AAD Log in and get AccessToken -- cca.acquireTokenByCode(tokenRequest): https://www.cnblogs.com/lulight/p/16357246.html” After the user logs in to the front-end application , Refer to the official example “Enable authentication in your own Node.js web API by using Azure Active Directory B2C : https://docs.microsoft.com/en-us/azure/active-directory-b2c/enable-authentication-in-node-web-app-with-api”.

First step : Download sample code

git clone https://github.com/Azure-Samples/active-directory-b2c-javascript-nodejs-webapi.git

Install app dependencies

cd active-directory-b2c-javascript-nodejs-webapi

npm install

npm update

The downloaded file structure is :

The second step : modify config.json Document and index.js Medium  identityMetadata value

options Middle is  BearerStrategy Configuration parameters for , Because it is not applicable at present AAD B2C, But directly AAD, therefore isB2C It needs to be set to false,

const options = {
identityMetadata: 'https://login.partner.microsoftonline.cn/xxxxxxxx-66d7-xxxx-8f9f-xxxxxxxxxxxx/v2.0/.well-known/openid-configuration',
clientID: ##clientID,
audience: ##clientID,
validateIssuer: true,
loggingLevel: 'info',
passReqToCallback: false
}

Because the test used in the reference document AAD B2C To certify Token, In this example, we use AAD To certify Token, So many parameter configurations are slightly different . BearerStrategy The detailed parameters of are as follows :

  • identityMetadata (Required)

    The metadata endpoint provided by the Microsoft Identity Portal that provides the keys and other important information at runtime. Examples:

    • v1 tenant-specific endpoint
      https://login.microsoftonline.com/your_tenant_name.onmicrosoft.com/.well-known/openid-configuration
    https://login.microsoftonline.com/your_tenant_guid/.well-known/openid-configuration
    • v1 common endpoint
      https://login.microsoftonline.com/common/.well-known/openid-configuration
    • v2 tenant-specific endpoint
      https://login.microsoftonline.com/your_tenant_name.onmicrosoft.com/v2.0/.well-known/openid-configuration
    https://login.microsoftonline.com/your_tenant_guid/v2.0/.well-known/openid-configuration
    • v2 common endpoint
      https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

    For B2C, you can only use v2 tenant-specific endpoint.

  • clientID (Required)

    The client ID of your application in AAD (Azure Active Directory)

  • passReqToCallback (Conditional)

    Required to set to true if using req as the first paramter in the verify function, default value is false. See section 4.2.1.3 for more details.

  • isB2C (Conditional)

    Required to set to true if you are using B2C tenant.

  • policyName (Conditional)

    Required if you are using B2C tenant. It is a string starting with 'B2C_1_' (case insensitive).

  • validateIssuer (Conditional)

    Required to set to false if you don't want to validate issuer, default value is true. We validate the iss claim in id_token against user provided issuer values and the issuer value we get from tenant-specific endpoint. If you use common endpoint for identityMetadata and you want to validate issuer, then you must provide issuer, or provide tenantIdOrName in passport.authenticate.

  • issuer (Conditional)

    This can be a string or an array of strings. See validateIssuer for the situation that requires issuer.

  • allowMultiAudiencesInToken (Conditional)

    Required if you allow access_token whose aud claim contains multiple values.

  • scope (Optional)

    This value is an array of scopes you accept. If this value is provided, we will check if the token contains one of these accepted scopes. If this value is not provided, we won't check token scopes.

  • audience (Optional)

    Must be a string or an array of strings. We invalidate the aud claim in access_token against audience. The default value for audience is clientID.

  • loggingLevel (Optional)

    Logging level. 'info', 'warn' or 'error'.

  • loggingNoPII (Optional)

    If this is set to true, no personal information such as tokens and claims will be logged. The default value is true.

  • clockSkew (Optional)

    This value is the clock skew (in seconds) allowed in token validation. It must be a positive integer. The default value is 300 seconds.

  • proxy (optional)

This value is the proxy settings object: { port: 'proxyport', host: 'proxyhost', protocol: 'http' }

Document address https://github.com/AzureAD/passport-azure-ad#42-bearerstrategy

The third step : visit API Interface (/hello need Authorization, /public Unwanted Authorization)

stay index.js In the code , Two interfaces are implemented /hello and /public. /hello Interface added passport.authenticate authentication , Access needs to carry Authorization (JWT Token), and /public No certification is required .

//<ms_docref_protected_api_endpoint>
// API endpoint, one must present a bearer accessToken to access this endpoint
app.get('/hello',
passport.authenticate('oauth-bearer', {session: false}),
(req, res) => {
console.log(req.headers.authorization);
console.log('Validated claims: ', req.authInfo); // Service relies on the name claim.
res.status(200).json({'name': req.authInfo['name']});
}
);
//</ms_docref_protected_api_endpoint> //<ms_docref_anonymous_api_endpoint>
// API anonymous endpoint, returns a date to the caller.
app.get('/public', (req, res) => res.send( {'date': new Date() } ));
//</ms_docref_anonymous_api_endpoint>

Verification effect :

Step four : verification idToken and accessToken

On the front end UI After logging in, you can get Token Information , http://localhost:3000/auth

Verify presentation animation :

Use accessTokne Error log for

{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.authenticate: received metadata","time":"2022-06-11T06:15:43.024Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.authenticate: we will validate the options","time":"2022-06-11T06:15:43.025Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.authenticate: access_token is received from request header","time":"2022-06-11T06:15:43.025Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.jwtVerify: token is decoded","time":"2022-06-11T06:15:43.027Z","v":0}
{"name":"AzureAD: Metadata Parser","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"working on key","time":"2022-06-11T06:15:43.028Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"PEMkey generated","time":"2022-06-11T06:15:43.033Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"authentication failed due to: In Strategy.prototype.jwtVerify: cannot verify token","time":"2022-06-11T06:15:43.036Z","v":0}

GET /hello 401 1.556 ms - -

Use idToken Correct log for

{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.authenticate: received metadata","time":"2022-06-11T06:16:25.102Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.authenticate: we will validate the options","time":"2022-06-11T06:16:25.102Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.authenticate: access_token is received from request header","time":"2022-06-11T06:16:25.103Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.jwtVerify: token is decoded","time":"2022-06-11T06:16:25.104Z","v":0}
{"name":"AzureAD: Metadata Parser","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"working on key","time":"2022-06-11T06:16:25.104Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"PEMkey generated","time":"2022-06-11T06:16:25.105Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.jwtVerify: token is verified","time":"2022-06-11T06:16:25.107Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"MININT-S4MGVOU","pid":17316,"level":30,"msg":"In Strategy.prototype.jwtVerify: We did not pass Req back to Callback","time":"2022-06-11T06:16:25.107Z","v":0}
Validated claims: {
aud: 'xxxxx-c6fd-xxx-9dac-xxxxxx',
iss: 'https://login.partner.microsoftonline.cn/xxxxx-c6fd-xxx-9dac-xxxxxx/v2.0',
iat: 1654924192,
nbf: 1654924192,
exp: 1654928092,
name: 'your name here',
oid: 'xxxxx-c6fd-xxx-9dac-xxxxxx',
preferred_username: '[email protected]',
rh: '0.xxxxxxxxx-xxxxxxxxxxxxxx.',
sub: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
tid: 'x-66d7-47a8-xx-xxx',
uti: 'xxxxxxxxxxxxxxxxxxxxxxxxx',
ver: '2.0'
}
GET /hello 200 11.557 ms - 16

[ Optional ] Step five : modify AAD Sign up for the app accessTokenAcceptedVersion

Because China AAD Currently generated Token by OAuth v1.0, And in the API Application  identityMetadata  It uses v2.0 Of openid-configration. So you need to be in ADD Modify the manifest file of the current registered application (Mainfest) in

accessTokenAcceptedVersion The value is 2 
  1. Sign in Azure Gateway , choice Azure AD.
  2. Click on  App registrations And choose your own application , As in this example “ExpressWebApp”
  3. Entry application Overview After the page , Select left navigation “Manifest” List page . modify accessTokenAcceptedVersion The value of is 2, Save it .

Reference material

Configure authentication in a sample Node.js web API by using Azure Active Directory B2C: https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-in-sample-node-web-app-with-api#step-4-get-the-web-api-sample-code

Microsoft Azure Active Directory Passport.js Plug-Inhttps://github.com/AzureAD/passport-azure-ad#42-bearerstrategy

Tutorial: Sign in users and acquire a token for Microsoft Graph in a Node.js & Express web apphttps://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal

Example: Acquiring tokens with ADAL Node vs. MSAL Nodehttps://docs.microsoft.com/en-us/azure/active-directory/develop/msal-node-migration#example-acquiring-tokens-with-adal-node-vs-msal-node

NodeJS Express + MSAL Application implementation AAD Integrated login and deployment in App Service Linux Implementation steps in the environment https://www.cnblogs.com/lulight/p/16353145.html

NodeJS Express + MSAL Application implementation AAD Log in and get AccessToken -- cca.acquireTokenByCode(tokenRequest):https://www.cnblogs.com/lulight/p/16357246.html

【Azure Application service 】NodeJS Express + MSAL Realization API application Token authentication (AAD OAuth2 idToken) Certification experiment for -- passport.authenticate('oauth-bearer', {session: false}) More articles about

  1. nodejs+express+mongodb Write api A simple attempt at interface

    1: start-up mongodb service my mongoDB Installation directory :E:\mongoDB\bin, edition :3.4.9 open cmd  -> e:( Get into e disc ) -> cd mongoDB/bin( Get into mo ...

  2. Azure In application services API application 、ASP.NET and Swagger introduction

    Learning content : How to use Visual Studio 2015 The built-in tools in Azure Create and deploy in application services API application . How to use Swashbuckle NuGet Package dynamic generation Swagger ...

  3. NodeJs Interface token authentication express frame passport Realization way Bearer authentication

    1. Generate a simple express project ( command :express passport-test), The project structure is as follows : 2. Add project dependency : npm install passport --save npm insta ...

  4. Nodejs Express 4.X chinese API 1--- Application piece

    Related reading : Express 4.X API translate [ One ] --  Application piece Express4.XApi translate [ Two ] --  Request piece Express4.XApi translate [ 3、 ... and ] -- ...

  5. Nodejs Express 4.X chinese API 4--- Router piece

    Related reading : Express 4.X API translate [ One ] --  Application piece Express4.XApi translate [ Two ] --  Request piece Express4.XApi translate [ 3、 ... and ] -- ...

  6. Nodejs Express 4.X chinese API 3--- Response piece

    Related reading : Express 4.X API translate [ One ] --  Application piece Express4.XApi translate [ Two ] --  Request piece Express4.XApi translate [ 3、 ... and ] -- ...

  7. Nodejs Express 4.X chinese API 2--- Request piece

    Related reading : Express 4.X API translate [ One ] --  Application piece Express4.XApi translate [ Two ] --  Request piece Express4.XApi translate [ 3、 ... and ] -- ...

  8. use nodejs,express,ejs,mongo,extjs Realized a simple website background management system

    Source code download address :http://download.csdn.net/detail/guoyongrong/6498611 This system is actually for learning nodejs The purpose of rewriting the system . The original system front-end uses ex ...

  9. NodeJS+Express+MongoDB Simple implementation of data entry and display 【 It's suitable for new people who just come into contact with learning 】

    Looking at it recently NodeJS relevant Have to say NodeJS+Express It's good to develop a website , For people who like to play JS It's really a good one Web Development Portfolio In contact with NodeJS It's time, it's time Java perhaps C# in API Interface, etc ...

  10. NodeJS+Express+MongoDB

    One .MongoDB MongoDB It's open source. , High performance NoSQL database : Support the index . colony . Replication and failover . There are many drivers in various languages : High scalability :MongoDB Is a database based on distributed file storage . from C++ Language ...

Random recommendation

  1. Machine learning six --K-means clustering algorithm

    Machine learning six --K-means clustering algorithm Think about common classification algorithms, such as decision tree .Logistic Return to .SVM. Bayes, etc . Classification as a method of supervised learning , It is required that all categories of information be known in advance , And assert that all items to be classified have a category ...

  2. error LNK2038: detected “_ITERATOR_DEBUG_LEVEL” Mismatches for : value “0” Mismatch value “2”

    error: vtkCommon.lib(vtkSmartPointerBase.obj) : error LNK2038: detected “_ITERATOR_DEBUG_LEVEL” Mismatches for : value “0” No ...

  3. Java Basics (51):Super And this The difference between

    1.      Subclass constructor if you want to reference super Words , Must take super At the top of the function . class Base { Base() { System.out.println("Base" ...

  4. Build AssetBundle, missing shader.

    Build AssetBundle, missing shader. 0   My uniy version is 4.1.2f1. Every asset file packing to a sin ...

  5. php Random verification code

    Today, my classmates asked me , use php How to write verification code , As a novice, it took half a day to finish . And the function is very simple . Today I was going to write session and cookie It seems to be tomorrow . <?php $image_width= ...

  6. cdoj 574 High-level ancients dfs order + Line segment tree

    High-level ancients Time Limit: 20 Sec Memory Limit: 256 MB Topic linking http://acm.uestc.edu.cn/#/problem/s ...

  7. win8.1 Disk usage 100 resolvent

    Close Homegroup , Because this feature will cause the hard disk and CPU In high load condition . Close method :Win+C – Set up – Change computer settings – Homegroup – If you can't use the Homegroup after leaving, you can turn off the Homegroup service directly : Control panel – Management tools – ...

  8. To configure SecureCRT Connect Linux CentOS

    Link address :http://f.dataguru.cn/thread-144513-1-1.html Environmental Science :Linux:centos5.8 virtual machine :VirtualBox This machine :windows As for how to install Cen ...

  9. struts2 High risk Remote Code Execution Vulnerability , Can cause the server to be invaded , Download the latest version to repair

          Struts2 A new high-risk Remote Code Execution Vulnerability was found , Can cause the server to be invaded , As long as it is Struts2 edition   lower than  2.3.14.3  All exist this vulnerability . At present, the official has released the latest version for repair . Please put stru ...

  10. CAD User selected entity in

    stay CAD In many operations of the, you need to select an entity , Here, I will share the methods used in my recent projects , The original intention of the program is to let the user select a single line of text or multiple lines of text , And return the contents of the selected text , Go straight to the code : CString CPaint ...