felixheck / hapi-auth-keycloak Goto Github PK
View Code? Open in Web Editor NEWJSON Web Token based Authentication powered by Keycloak
License: MIT License
JSON Web Token based Authentication powered by Keycloak
License: MIT License
Hi i',m having trouble using scopes with the jwt and this.
The jwt has in the root a field named scope wich is a string of different scopes, separated by a whitespace.
I've played around in the src code of the library, and it seems like token.js line 50
const scopes = _.flatten(_.map(auth.permissions, 'scopes')).map(prefix('scope'))
does not return any scopes. I know the scope is present. If i on line 50-51, add the unpacking og scope variable, and console.log it it shows me my scopes.
The function returns the scope as an empty list. This is a problem for me.
If I change line
const scopes = _.flatten(_.map(auth.permissions, 'scopes')).map(prefix('scope'))
to const scopes = scope.split(" ").map(s => `scope:${s}`);
it works
token.js
function getRoles (clientId, {
realm_access: realm = { roles: [] },
resource_access: resources = {},
authorization: auth = { permissions: [] },
scope
}) {
const prefix = prefixRole.bind(undefined, clientId)
const realmRoles = realm.roles.map(prefix('realm'))
// const scopes = _.flatten(_.map(auth.permissions, 'scopes')).map(prefix('scope'))
const scopes = scope.split(" ").map(s => `scope:${s}`);
const appRoles = Object.keys(resources).map((key) => resources[key].roles.map(prefix(key)))
return _.flattenDepth([realmRoles, scopes, appRoles], 2)
}```
Hi @felixheck - I have borrowed your example code in the readme (https://github.com/felixheck/hapi-auth-keycloak#example) but I am a little unsure where to go from there.
I attempted to use client/secret method by adding my Keycloak client's clientId
and secret
to my options object, but I still see:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing or invalid authorization header",
"attributes": {
"strategy": "keycloak-jwt",
"error": "Missing or invalid authorization header"
}
}
I dug in a little bit and I can see that an Authorization header with bearer token is expected. So is every request to my Hapi endpoint expected to have this header set? That would make sense since the bearer token is user specific and needed in order to correctly authorize the user. After reading your reply in #8, it sounds like the job of getting the bearer token falls outside the responsibility of hapi-auth-keycloak. Is this correct?
tail
async
/await
This code is calling validate token:
https://github.com/felixheck/hapi-auth-keycloak/blob/master/src/index.js#L33
But validate token has an extra parameter expectedType
:
https://github.com/keycloak/keycloak-nodejs-connect/blob/master/middleware/auth-utils/grant-manager.js#L428
Because that field is undefined if the typ field from token is filled with anything the validation will fail.
I have in a token generated by Keycloak, in payload, the following content:
{
...
"typ": "Bearer",
...
}
So the comparison is made with undefined
.
Looks to me that a Bearer
string should be passed as param in the validate call from the hapi plugin.
What do you think? Is this a bug?
How to make actual redirection to keycloak login window.
I thouth it will be done if request is not authorized.
But I just get 401 Unauthorized.
Hey,
I was wondering if you ever considered extending this plugin to allow it to be reused for different client/realms?
My goal is to have different routes in my application being authenticated by different client/realms than other routes.
I think the only change one would need is to make the strategy name keycloak-jwt
and maybe the decorator kjwt
flexible through the options.
Best
Jonathan
In a live production environment my options look like this:
options: {
realmUrl: 'https://mykeycloak.com/auth/realms/myrealm',
clientId: 'myclientid',
}
... so the publicKey is pulled from my Keycloak server and cached on first use as I understand it. Is that right?
While writing some integration tests around authentication, I created a key-pair and corresponding valid JWT, then set the options like this:
options: {
realmUrl: 'http://nonexistanturl.nonexistant',
clientId: 'testclientid',
publicKey: 'string representation of publicKey in PEM format'
}
running a test using the valid JWT I created, this is the response.result I'm getting:
{
statusCode: 401,
error: 'Unauthorized',
message: 'Invalid credentials',
attributes:
{
strategy: 'keycloak-jwt',
reason: 'invalid token (wrong ISS)',
error: 'Invalid credentials'
}
}
not what I expected. After some fiddling, the only way I could get this working was to set realmUrl to localhost
options: {
realmUrl: 'http://localhost',
clientId: 'testclientid',
publicKey: 'string representation of publicKey in PEM format'
}
then the response.result is what I would expect with a valid JWT. NOTE - The 400 is from the graphql layer which tells me the JWT is valid.
{
statusCode: 400,
error: 'Bad Request',
message: 'GET query missing.'
}
shouldn't the presence of the 'publicKey' option override the realmUrl key?
I'm trying to implement optional authentication using mode: 'optional'
.
For it to work, the error response on unauthorized requests (e.g. without an authorization header) must return boom.unauthorized(null, schema)
.
A quick search resulted in the regarding lines:
Not sure what the best way to implement it is, looking at
return boom.unauthorized(err ? err.message : msg, scheme, ...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.