Reputation: 393
I'm trying to figure out how to do the identity server 4 authentication below using NodeJS - way out of my comfort zone here.
services.AddAuthentication(IdentityServerAuthenticationDefaults
.AuthenticationScheme)
.AddIdentityServerAuthentication(
options =>
{
options.Authority = "<authority-url>";
options.ApiName = "<api-url>";
});
I'm missing something in the flow here as the C# implementation isn't provided a secret or similar - so the token is probably verified via identity server? How would I verify the token using NodeJS if I don't have a 'secret' to verify it with?
I've stumbled on introspection endpoint - am I heading in the right direction?
Upvotes: 6
Views: 9557
Reputation: 14872
If you want only to validate your token you can use the following package:
npm install token-introspection --save
This package is configured with endpoint and client credentials, and a function is returned. Calling that function with token, and optional token_type_hint will return a Promise.
const tokenIntrospection = require('token-introspection')({
endpoint: 'https://example.com/introspect',
client_id: '<Client ID>',
client_secret: '<Client Secret>',
});
tokenIntrospection(token).then(console.log).catch(console.warn);
Example :
Here is a middleware to validate the token :
module.exports = (req, res, next) => {
const token = "wEvxS0y2TkvCjLpKP33oGTK0BcKUb6MHt1u3AeMu8h4"; // get your token from your request
const tokenIntrospection = require('token-introspection')({
endpoint: 'http://localhost:5000/connect/introspect',
client_id: 'api1',
client_secret: 'apisecret',
});
tokenIntrospection(token).then(result => {
console.log(result);
next();
}).catch(console.warn);
}
then you can use it as below :
const auth = require('./atuh')
app.get('/', auth, (req, res, next) => {
res.send("Hi");
})
Upvotes: 0
Reputation: 85
The accepted question is right. but i wanted to fix some of it's trial errors.
you can easily (it took me 4 days) add authentication to your express api
with ids4
.
it's how its work:
creating a middleware:
const jwt = require("express-jwt"),
jwksClient = require("jwks-rsa");
const auth = jwt({
secret: jwksClient.expressJwtSecret({
cache: true, // see https://github.com/auth0/node-jwks-rsa#caching
rateLimit: true, // see https://github.com/auth0/node-jwks-rsa#rate-limiting
jwksRequestsPerMinute: 2,
jwksUri: `${issuer}/.well-known/openid-configuration/jwks`,
}),
audience: "api1.resource", // <---- its your api resource.
issuer: issuer, // <----- address of identityserver4.
algorithms: ["RS256"], //<----- its needed algorithm to handle secret.
});
The following auth middleware
is like following code in .net:
services.AddAuthentication(IdentityServerAuthenticationDefaults
.AuthenticationScheme)
.AddIdentityServerAuthentication(
options =>
{
options.Authority = "<authority-url>";
options.ApiName = "<api-url>";
});
to secure a nodejs
route you can use following example:
// this is the secured route by identityserver4
// the jwt module set the ids4 auth result in req.user object
// so you can use it to access logged in user claims and stuff.
// for example testing with client credentials it return some info about the jwt token sent to the /me endpoint.
app.get("/me", auth, (req, res) => {
const user = req.user;
debug("req.user: %O", user);
return res.json(user);
});
// this a unsecured route. so anyone can call this route without any restrictions.
app.get("/", (req, res) => {
return res.send("Hello");
});
It takes me so long to find how to secure nodejs
or express with identityserver4
but it was as simple as it look like.
The code here is from the following identityserver4
community example with full ids4
and node api
and javascript client and .net console client:
https://github.com/lyphtec/idsvr4-node-jwks
There is a good documentation about this example in its own github
repository too.
You can download the node api
and run it with yarn start
or npm run start
.
I tested it with client credentials flow and it worked like a charm.
Wish all of you luck.
Upvotes: 3
Reputation: 393
I was able to solve this using the jwks -endpoint and it's public keys to verify tokens and then I also found a nice package that I used to prepare the middleware:
private issuer: string = process.env.idsrv;
auth = jwt({
secret: jwksClient.expressJwtSecret({
cache: true, // see https://github.com/auth0/node-jwks-rsa#caching,
cacheMaxAge: ms('24h'),
rateLimit: true, // see https://github.com/auth0/node-jwks-rsa#rate-limiting
jwksRequestsPerMinute: 100,
jwksUri: `${this.issuer}/.well-known/jwks`
}),
// validate the audience & issuer from received token vs JWKS endpoint
audience: `${this.issuer}/resources`,
issuer: this.issuer,
algorithms: ["RS256"]
});
Upvotes: 5