Coder Social home page Coder Social logo

azure-samples / active-directory-javascript-nodejs-webapi-v2 Goto Github PK

View Code? Open in Web Editor NEW
75.0 46.0 41.0 128 KB

A small Node.js Web API that is protected with Azure AD v2.0 to validate access tokens and accepts authorized calls using Passport.js

License: MIT License

JavaScript 13.10% PowerShell 86.90%
javascript oauth2 webapi azure-ad passport-js nodejs

active-directory-javascript-nodejs-webapi-v2's Introduction

active-directory-javascript-nodejs-webapi-v2's People

Contributors

afermon avatar danieldobalian avatar derisen avatar jmprieur avatar joeho888 avatar kalyankrishna1 avatar kjyam98 avatar microsoftopensource avatar msftgits avatar navyasric avatar salman90 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

active-directory-javascript-nodejs-webapi-v2's Issues

Another 404

  • bug report -> please search issues before submitting
  • feature request
  • documentation issue or request
  • regression (a behavior that used to work and stopped in a new release)

### Minimal steps to reproduce
> Click on the example "here" link in the "Exploring the sample" section

### Any log messages given by the failure
> N/A

### Expected/desired behavior
> Directs to the correct link


### Mention any other details that might be useful

I tried using the "Angular Single-page application with MSAL-Angular using the implicit flow" client
to connect with this sample and followed all available instructions but when I press "Login" and
provide my credentials I'm met with: "unauthorized_client: The client does not exist or is not enabled
for consumers. If you are the application developer, configure a new application through the App
Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908."


I tried to use the sample at the link instead but it's another 404


> ---------------------------------------------------------------
> Thanks! We'll be in touch soon.

How to get reason of token validation failure?

I have cloned this repo and running it locally. I have been able to run it successfully with valid token. For invalid tokens,, the API only returns 401, Unauthorized. How can I get the actual reason for failure like token expiry or invalid audience?
It would be great if you can point me to some code sample.

Is it best practice to use sessions?

Library

Description

I've asked the same question on StackOverflow without any response so I'll try it here again.

I'm very new to web development but I've manged to set up a client and server app. The front-end uses msal.js to authenticate the user to Azure AD and the backend receives the access_token and verifies if the token is valid with passport-azure-ad. This is the token flow:
enter image description here

So far all is working fine except that I'm wondering how it would work on heavy load. In the Microsoft example they set the session to false.

// API endpoint
app.get("/hello",
    passport.authenticate('oauth-bearer', {session: false}),

This probably makes passport verify each and every call. Might this be an issue when invoked many times? We use passport as middlewware for graphql queries, nutations, resolvers, ...

  app.use(passport.initialize())
  passport.use(bearerStrategy)

  app.use(
    passport.authenticate('oauth-bearer', { session: false }),
    (req, _res, next) => {
      console.log('User info: ', req.user)
      console.log('Validated claims: ', req.authInfo)
      next()
    }
  )

This is a bit unclear from the docs of the bearerStrategy for our v2 endpoint. If this becomes an issue it might be needed to create a graphql login and logout resolver that is only called when a user logs in and set up a session on the backend.

Thank you for helping to clear up my confusion.

req.user is undefined

I'm having a similar issue as this one. Following the example I have this code in index.ts:

import 'reflect-metadata'
import 'tsconfig-paths/register'
import express from 'express'
import passport from 'passport'
import { BearerStrategy, } from 'passport-azure-ad'
import { ENVIRONMENT } from '@environment'
import { createConnections } from 'typeorm'
import { getApolloServer } from '@utils/apollo'
import cors from 'cors'

const app = express()

const bearerStrategy = new BearerStrategy(
  {
    identityMetadata: 'https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx/v2.0/.well-known/openid-configuration',
    clientID: 'xxx-xxx-xxx-xxx-xxx',
    validateIssuer: false,
    loggingLevel: 'info',
    passReqToCallback: false,
  },
  (token, done) => {
    // Send user info using the second argument
    done(null, {}, token)
  }
)
app.use(cors({ origin: true }))
app.use(passport.initialize())
passport.use(bearerStrategy)

app.use(
  passport.authenticate('oauth-bearer', { session: false }),
  (req, res, next) => {
    console.log('User info: ', req.user)
    console.log('Validated claims: ', req.authInfo)
    next()
  }
)
;(async () => {
  try {
    await createConnections()
    const server = await getApolloServer()
    server.applyMiddleware({ app, cors: false })

    app
      .listen({ port: ENVIRONMENT.port }, () => {
       console.log( `Server ready at http://localhost:${ENVIRONMENT.port}${server.graphqlPath}` )
      })
      .on('error', function (error) { throw `Failed starting Express server on port ${ENVIRONMENT.port}: ${error}` })
  } catch (error) {
    console.error(`Failed starting server: ${error}`);  process.exit(1)
  }
})()

Which results in these console logs:

User info:  {}
Validated claims:  {
  aud: 'xxx-xxx-xxx-xxx-xxx',
  iss: 'https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx/v2.0',
  iat: 1595582006,
  nbf: 1595582006,
  exp: 1595585906,
  aio: 'xxx/xxx/xxx/xxx/',
  azp: 'xxx-xxx-xxx-xxx-xxx',
  azpacr: '0',
  name: 'Bond, James (London) GBR',
  oid: 'xxx-xxx-xxx-xxx-xxx',
  preferred_username: '[email protected]',
  rh: 'x.xxxxxxxxx.',
  scp: 'access_as_user',
  sub: 'x-x-xxx-xxx-xxx',
  tid: 'xxx-xxx-xxx-xxx-xxx',
  uti: 'xxx-xxx',
  ver: '2.0'
}

Notice that he req.user is undefined. According to the documentation I would expect passport to set this for us? Or am I missing something here? To store the user in the database we should probably use the field oid as unique identifier?

A similar question on StackOverlflow.

Thank you for your help.

cannot get AAD Federation metadata from endpoint you specified

I'm having a similar issue as this one. Upon app start all is fine and no error is displayed:

{"name":"AzureAD: Bearer Strategy","hostname":"BELSGFRANIT04","pid":1900,"level":40,"msg":"Production environments should always validate the issuer.","time":"2020-07-06T07:27:08.881Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"BELSGFRANIT04","pid":1900,"level":30,"msg":"In BearerStrategy constructor: strategy created","time":"2020-07-06T07:27:08.883Z","v":0}
Listening on port 5000

Then when visiting the protected route http://localhost:5000/hello with the brwoser (unauthorized) we get this:

{"name":"AzureAD: Metadata Parser","hostname":"BELSGFRANIT04","pid":1900,"level":50,"msg":"cannot get AAD Federation metadata from endpoint you specified","time":"2020-07-06T07:29:08.102Z","v":0}
{"name":"AzureAD: Metadata Parser","hostname":"BELSGFRANIT04","pid":1900,"level":50,"msg":"cannot get AAD Federation metadata from endpoint you specified","time":"2020-07-06T07:29:08.102Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"BELSGFRANIT04","pid":1900,"level":30,"msg":"authentication failed due to: Error: Cannot get AAD Federation metadata","time":"2020-07-06T07:29:08.104Z","v":0}
GET /hello 401 163.631 ms - -

This happens with the latest sample.

config.js

const config = {
    identityMetadata: "https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx",
    clientID: "xxx-xxx-xxx-xxx-xxx",
    validateIssuer: false,
    loggingLevel: 'info',
    passReqToCallback: false
};

module.exports = config

Documentation

Tried what is mentioned in documentation.

localhost:5000/hello responds with 401 Unauthorized.

Tried these scenarios too.

  1. Changing the realm to the directoryID from "common"
  2. Changing the reply URL of the application in AD to localhost:5000/

Not sure what steps are missing to correct this error. Is there a client secret to be used?

Authentication failed due to: In Strategy.prototype.jwtVerify: cannot verify token

Hi there,

After following theses tutorials: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis & https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis, I'm getting this error message when trying to GET /hello using react:
authentication failed due to: In Strategy.prototype.jwtVerify: cannot verify token

Here's the full trace:

{"name":"AzureAD: Bearer Strategy","hostname":"Kylian","pid":18560,"level":30,"msg":"In Strategy.prototype.authenticate: received metadata","time":"2020-06-24T16:30:49.636Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"Kylian","pid":18560,"level":30,"msg":"In Strategy.prototype.authenticate: we will validate the options","time":"2020-06-24T16:30:49.655Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"Kylian","pid":18560,"level":30,"msg":"In Strategy.prototype.authenticate: access_token is received from request header","time":"2020-06-24T16:30:49.655Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"Kylian","pid":18560,"level":30,"msg":"In Strategy.prototype.jwtVerify: token is decoded","time":"2020-06-24T16:30:49.656Z","v":0}
{"name":"AzureAD: Metadata Parser","hostname":"Kylian","pid":18560,"level":30,"msg":"working on key","time":"2020-06-24T16:30:49.656Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"Kylian","pid":18560,"level":30,"msg":"PEMkey generated","time":"2020-06-24T16:30:49.657Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"Kylian","pid":18560,"level":30,"msg":"authentication failed due to: In Strategy.prototype.jwtVerify: cannot verify token","time":"2020-06-24T16:30:49.675Z","v":0}

Here's my code from react side:

try {
            const accessToken = await this.userAgentApplication.acquireTokenSilent({
                scopes: scopes
            });

            if (accessToken) {
                console.log(accessToken);
                ....
                fetch("http://localhost:5000/hello", {
                    method: 'GET',
                    headers: {
                        "Authorization": `Bearer ${accessToken.accessToken}`,
                        "Content-Type": 'application/json'
                    }
                })
            }
        } catch (err) {
            ...
        }
    }

Here's the config.js file:

const config = {
    identityMetadata: "https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration",
    clientID: <client-id>,
    validateIssuer: false,
    loggingLevel: 'info',
    passReqToCallback: false
};

module.exports = config

Am I doing something wrong ?
I did a lot of search on google and I still can't find where is the problem :/

Regards,

Kilio22

Documentation

The Documentation mentions a server.js file. But there is none present. Remove that please.

The client links in the overview are 404'd

  • bug report -> please search issues before submitting
  • feature request
  • documentation issue or request
  • regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

click on either client link in the Overview

Any log messages given by the failure

N/A

Expected/desired behavior

to be directed to the client application(s) in question

dead link?

Please provide us with the following information:

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [ ] feature request
- [X ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

The link in the second paragraph of the Overview section appears to be broken: "JavaScript Single-page application & Node.js web API Tutorial". Is that supposed to go here: ms-identity-javascript-tutorial ?

Is the intention to use that tutorial alongside this one?
ms-identity-javascript-tutorial
active-directory-javascript-nodejs-webapi-v2

LONG STORY SHORT: I've got raw JavaScript on the frontend, and Node on the backend w/MSSQL.... all on premise.

Thanks!

Authentication failed due to: jwt audience is invalid

Please provide us with the following information:

This issue is for a: (mark with an x)

- [x ] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

image

{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-HT9EEDQ","pid":18344,"level":30,"msg":"authentication failed due to: jwt audience is invalid","time":"2021-07-16T21:46:23.124Z","v":0}

authentication failed due to: jwt audience is invalid
When I press HelloAPi I'm getting this error

Any log messages given by the failure

image

Expected/desired behavior

normal

OS and Version?

Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)

Versions

Mention any other details that might be useful


Thanks! We'll be in touch soon.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.