I am trying to get a login procedure to work in AWS by following the Enhanced Authflow for Developer Authentication mentioned in the official documentation.
The code in both client and server are using JavaScript, and I'm using Node.js on the server-side.
I have managed to get the OpenId token back to the client but when I try to exchange it for credentials by calling getCredentialsForIdentity(), the client receives this error:
NotAuthorizedException: Access to Identity 'eu-west-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' is forbidden.
Also on the server-side when I print the variable holding my AWS.CognitoIdentity object and check the property cognitoidentity.config.credentialProvider all I get is:
{"providers":[null,null,null,null]}
It feels like the named custom developer provider I have associated with my identity pool should be in there but I seem to not be able to get it there.
Any thoughts on where I might have gone wrong?
That error is usually thrown when you try to get access to an authenticated id without providing any of the tokens linked to that identity. If it's an authenticated identity, make sure you are giving a token for it.
Related
I'm trying to setup a OneLogin mocked service locally using WireMock. So far so good, I was able to mock most of the OAuth OneLogin flow but I can't manage to solve the last part in order to get it working properly...
Whenever I submit credentials on my Mocked OneLogin page and it redirects me back to the application I get error: RPError: failed to validate JWT signature. From the debugging I discovered that the problem is in the mocked OneLogin server on the "jwks_uri": "http://localhost:27442/oidc/2/certs" endpoint. Seems the last part of NextAuth verification which is using jose..compactVerify(jwt, key instanceof Uint8Array ? key : key.keyObject) doesn't match what I've mocked thus not allowing me to proceed with mocked login.
Does anyone know what should the /oidc/2/certs endpoint return to match generated mocked token??
How should the JWT and return value of oidc/2/certs look like to be approved.
I generated JWT on https://jwt.io/
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY2NjAwMDgwMCwiZXhwIjoxNjY4Njc5MjAwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjI3NDQyL29pZGMvMiIsImF1ZCI6InNvbWUtY2xpZW50LWlkIn0.QLqLlhoZi7JnqTAYibPkIFPvmC88t4Z7AbUspSX8ENbEnK0NXV_hTxAXLA3-V7TjuIWlrJOvOT7BrHP3N39XV0Vb5pw_X4OY48ce9JQR46x5v3YeU4wgm48sWCIkwRVNDGV0_oF1Pr2Qa4egAVDzLDxtoqrgV4W_wjOI-jxv2r0NWeNvgsSH68PC0qTcgfuLG_k1Sf61CBS-_DKHGznD9gdHc3xJM2Rh3FLQQ5-JHVlE0nB0If8Gx-Q5_cI2VQaDwj-x4VO9qzE2o1zes41NgyP1D85TODegPN6lNvpLMyexIBwl5LYP0WnpW9ZDKziUqVLkuJ4LTnl5jg9ZsbXQ2Q
and looking at onelogin docs I found this https://acme.onelogin.com/oidc/2/certs
How can I match above to be verified successfully? I basically want an infinite JWT (RS256 alg) token that will be verified mitigating OneLogin flow in development environment
After fighting with this for several days I found a solution.
I had to Generate JWT token with appropriate header and payload values on https://jwt.io/#debugger-io then copy public key and generate JWK with it on
https://russelldavies.github.io/jwk-creator/
An otherwise working as expected Keycloak Server is giving me a headache since I started to try and implement Application Initiated Actions.
Prior Search
Because looking for the topic results in a sparse selection of hands-on material, I got to go through the design document for AIA, especially the flows section.
Environment
Keycloak 15
PostgreSQL Database Backend
Keycloak as k8s deployment
Client in use has temporary full scope for development purposes
Node.JS backend with keycloak-connect and express as the Server
What I've tried
According to the design document (Here is an entry to google groups where it's said that the feature "pretty much turned out as designed") flows should be constructed as
../realms/myrealm/protocol/openid-connect/auth
?response_type=code
&client_id=myclient
&redirect_uri=https://myclient.com
&kc_action=update_profile
which resulted in this code in my templating engine:
`${keycloak.config.realmUrl}/protocol/openid-connect/auth?response_type=code&client_id=${keycloak.config.clientId}&redirect_uri=${new URLSearchParams("http://localhost:3000/account").toString()}&kc_action=update_profile`
(pug variable) keycloak.config is filled using keycloak.getConfig() where keycloak is the keycloak-connect instance.
The templating engine correctly substitutes the variables into a link that leads to my keycloak instance, where I am presented with (the german equivalent of) this error message:
Unexpected error when handling authentication request to identity provider
(German:
Unerwarteter Fehler während der Bearbeitung der Anfrage an den Identity Provider.
)
There are no other identity providers configured.
Question
How to correctly make the call to my Keycloak to kick off an AIA, if the way described in the design document leads to this error?
After my own research, I now got it to work.
The error message seems misleading because I don't have another identity provider configured on that instance.
The kc_action parameter is expected to be in ALL CAPS. So
`${keycloak.config.realmUrl}/protocol/openid-connect/auth?response_type=code&client_id=${keycloak.config.clientId}&redirect_uri=${new URLSearchParams("http://localhost:3000/account").toString()}&kc_action=update_profile`
should be
`${keycloak.config.realmUrl}/protocol/openid-connect/auth?response_type=code&client_id=${keycloak.config.clientId}&redirect_uri=${new URLSearchParams("http://localhost:3000/account").toString()}&kc_action=UPDATE_PROFILE`
This needs to be documented somewhere for people to find, because I didn't see it explicitly mentioned in the "docs".
I also raised an enhancement request to the Keycloak documentation to document AIAs officially
We have a React client that uses AWS Cognito and Amplify ("aws-amplify": "1.1.40").
When a user logs in we want to send some additional data to Cognito, to be used by a "pre token generation" trigger. We do this by adding a clientMetadata ({"metadataKey1": "metadataValue1"}) object to the Auth.signIn function call:
Auth.signIn(auth.email, auth.password, {"metadataKey1": "metadataValue1"})
.then(response => {
// Sign in OK
})
.catch(error => {
// Something went wrong
});
This works as expected, and the Cognito "pre token generation" lambda can extract the "metadataKey1" from the clientMetadata in the request.
This is where our problem starts:
After the successful signIn, AWS Amplify automatically does a session refresh. This session refresh is not explicitly done by our code, and the clientMetadata object used during signIn is not set. This of course means that the automatic session refresh request to Cognito does not contain the clientMetadata, which in turn means that the Cognito "pre token generation" lambda can not extract "metadataKey1" from the clientMetadata in the request (as it does not exist).
We have debugged the code, and found that the automatic request to Cognito happens in #aws-amplify\auth\node_modules\amazon-cognito-identity-js\es\CognitoUser.js#1249, CognitoUser.prototype.refreshSession. The refreshSession function can receive a clientMetadata object, but when debugging the code the clientMetadata object is always undefined (which makes sense; we have not set it explicitly and the Amplify code does not seem to store/use the clientMetadata we set during signIn).
What we need help with:
Are we not doing enough? Do we have to do some other things in our code to make sure the clientMetadata object is sent on every request to Cognito, even requests that are not explicitly done by our code?
Are we doing it wrong? The goal is to make sure we can send our own data on every request to Cognito. Are there other ways to do this than use the clientMetadata object?
Would really appreciate any help with this!
According to API Reference, The ClientMetadata value is passed as input to the functions for ONLY the following triggers:
Pre signup
Pre authentication
User migration
I'm writing angular application that uses implicit grant oauth strategy. If I don't have valid access token in my cookies I am redirected to web interface of authentication server, input my credentials and get redirected to my site with access token in the url. My system parses it and writes down into cookies.
Currently I faced question of unit testing this parse function that consumes the url and returns access token object. Can't think the good way, so writing here:
1. How do you approach unit testing (so I can't make direct request to working oauth server) a function that parses the access token from authentication server?
2. How do you build url params with access token? Will it be secure if I copy current access token and use it in test data?
3. Are there libraries that can aid creation of mock access token object?
You could breakout "just enough" OAuth, like the service linked below. This will give you a super-basic OAuth provider, but is really geared to "integration testing" scenarios (depending on where you draw the lines on these things).
If you want to be a unit-testing purist/zealot, then you could fork this into your app's unit test code.
https://github.com/zalando-stups/mocks/tree/master/oauth2-provider
In lieu of a great answer, here's one to get you out of a hole :)
After approaching authors of my oAuth authentification service I've got insight on the data the server was sending me in case of successful authentication. In my case the response from oAuth server has the following form:
header // encoded algorithm for has creation
access token // base64 encoded object
hash // of the 3 previous items done using algorithm specified in the header.
It has the following structure: header.access_token.hash
My fear for security breach was concerned about putting correct data (that I can get from browser) into the test files. But as it turns out the token will not be valid without correct hash. The hashing of the token data is done in server side using private key, so if I change the hash the token will become obsolete.
As my token-parsing-function that I wanted to check uses only the access_token part of the request, I've changed the header and hash parts and also encoded other user name for sake of testing purposes.
So this is the resolution of my current problem. Hope this will help somebody.
Hi I hope someone can help with this because it's driving me crazy right now.
I am trying to replicate this Google API authorisation example https://code.google.com/p/google-api-javascript-client/source/browse/samples/authSample.html on my own web server http://james-gilmore.co.uk/test.html
I have duplicated the code but replaced the clientID and API key with the keys set up in the google api console and I have turned the Google+ api service on in the 'Services' section.
I have the following set up under 'Client ID for web applications'
Redirect URIs: http://james-gilmore.co.uk/oauth2callback
JavaScript origins: http://james-gilmore.co.uk
And I also have the following set up under 'Simple API Access'
Referers: .james-gilmore.co.uk/.
When I run the http://james-gilmore.co.uk/test.html script I can authorise my access but I can see a JS error generated in the console:
'Uncaught TypeError: Cannot read property 'url' of undefined'
Does anyone know what I could be doing incorrectly? I think it may have something to do with the setup of my client ID's and allowed Referers because when I run the following example https://code.google.com/apis/console/?api=plus it works fine
The OAuth authentication appears to be working, but I see an error Access Not Configured being returned from an AJAX call.
Set up your referers as james-gilmore.co.uk/* (with the trailing wildcard, so that it will allow anything starting with your domain name).