Comments (19)
I thought I did that, but I re-applied them and it works! Thank you so much for your help, I do really appreciate it.
from cloudfront-authorization-at-edge.
That shouldn't happen!
The URL you provided above isn't right, it doesn't contain a state, only a code.
How did you deploy the application? Through the serverless application repository or manually using CLI? (Question behind the question is, are you on the latest version of the code?)
If you are indeed on the latest version, can you open the network panel of your browser, and explain what you see going on in there? Which redirects are triggered, using which path patterns, etc.
from cloudfront-authorization-at-edge.
I used:
Option 1: Deploy through the Serverless Application Repository
I made no change to the 'Application settings', beside checking the box giving permissions.
After I goto Cognito and press the Open UI button (and then log in):
My network log has two hits...First:
Responds with a 302
Then https://ZZZZZZZZZZ.cloudfront.net/parseauth?code=de477e41-1bbc-4a07-b1ed-3a9746c86cd8 is hit, missing the state parameter (at least from my understanding), and returns a 400 stating:
Bad Request
ERROR: Error: Invalid query string. Your query string should include parameters "state" and "code"
Try again
from cloudfront-authorization-at-edge.
So the Cognito UI will call /login first asking for authentication, and then it replies with the code, and redirects it to the /parseAuth call. But because it hasn't hit check auth yet, there is no state yet. Does parseauth need better checking for this case, and then do another redirect around checkout (either the URL or the similar code) ?
from cloudfront-authorization-at-edge.
Ahh yes that's the issue. Opening the app using that link in Cognito User Pool doesn't work. You need to just go to the URL of the web app (as users would).
However the "Try again" button does bail you out right? To be honest, that seems fine then to me, as only admins would use that button in the Cognito UI.
On the other hand, other admins will run into this too, and might have the same question as you had. We could add that explanation to the error message "you probably got here through the button in Cognito ..... press Try again". Agree that that's good enough?
There might be other reasons why state wouldn't be present in the query string, think it is better to not do the "try again" automatically, have users click that button and keep visibility of this situation.
from cloudfront-authorization-at-edge.
My use case is that, each one of those "Open Cognito UI" buttons allows the passing of a client_id, which tells Cognito specifically "use this IDP" or "Use this User Pool". So ideally, on their IDP, I'll send them to the domain + query parameter. I think the solution is to add the ability to forward this parameter from the initial domain + query parameter into checkauth and have that call /authenticate with the code, which would then authenticate them though the correct portal.
from cloudfront-authorization-at-edge.
Also in terms of the larger project, wouldn't it be better to modify parseauth so that it can handle this case, such that it yields a successful login for the user? That would be a better UX.
from cloudfront-authorization-at-edge.
The state contains a nonce, which protects against CSRF. Other sites cannot just redirect users to the protected site, that is by security design.
It sounds though like that is precisely what you want to do, which is fine - if it makes sense in your use case.
Can you describe your use case in more detail? You want to federate Cognito to multiple IDP's, and have links that would go directly to any one of those IDP's instead of the Cognito Hosted being opened showing all the options? Is that it? Why is it important (I can guess but interested to hear you on this)
from cloudfront-authorization-at-edge.
Well each client would have their own client_id, and thus their own separate logins, with the Cognito User Pool login disabled. So having a client_id is required to be presented with the right IDP Cognito authentication page. Going to the URL directly would yield a blank page telling the user to go away (or something nicer). If I have 20 clients, I don't want 20 buttons that say "Login with X", "Login with Y", etc. I don't want my users to have to expose their IDP login systems to everyone else using the system.
from cloudfront-authorization-at-edge.
OKay makes sense.
And why one User Pool and one CloudFront distribution? Any particular reason?
from cloudfront-authorization-at-edge.
To me it made the most logical sense because if I had 200 different clients for my app, I'd have to have 200 distributions, plus 200 x 5 lambda functions for each client. (Since the lambdas are not re-usable in this fashion). So by having one Distribution, and one SPA, but multiple clients from the Cognito IDP stand-point, users can only authenticate with their IDP and I can use the identity providers Identifiers to know which client is logging into which backend.
from cloudfront-authorization-at-edge.
That would also mean 200 IDP's if I understand you correctly. Is that in any way realistic for you, can you shed some light on that? I'd like to talk real business use cases, and fully understand those.
The clientId is encoded in the Lambda functions now. So using multiple client ID's would require changing the way the Lambda's work.
A client would normally map to a SPA, you would not use multiple Client ID's for the same SPA. I mean, technically you can, but it it sounds like you're only doing it to have separate login URL's per IDP. That I can understand, but can also be solved with one Client ID. We would need to come up instead then with a way to let the checkAuth handler know what IDP it should redirect to.
At this point though, it doesn't sound like this requirement is generic enough, to be implemented here in this repo. But I'm happy to be convinced otherwise.
from cloudfront-authorization-at-edge.
I see, I guess I didn't realize till now that the lambdas have the client id hard coded into them. The business case for the multiple IDPs is that many of our clients have their own SAML and we want to partner with them to allow them to connect their SAML to our Cognito provider, and thus give them access to our app via their authentication. For now we have a few clients, but in the future it could go way up.
At this point the only option with this is to have multiple clients, but then use multiple CloudFront instances, with multiple lambdas.
from cloudfront-authorization-at-edge.
A way to do it:
- have one client, one user pool, one cloudfront dist
- create the federation IDP's, give each one a unique ID, readable or obfuscated (what you want)
- update the checkauth lambda so that it reads the URL query param "idp_identifier". If it is not there throw error, if it is there (and user is not signed in) redirect to cognito and pass along the idp_identifier param. If that is present Cognito will not show HostedUI but go to that IDP directly.
So e.g. if you had setup federation for company A, name that IDP companyA and then with above change in checkAuth in place the user has to go to e.g.: https://example.com/some/path?idp_identifier=companyA
Read here about that param "idp_identifier": https://docs.aws.amazon.com/cognito/latest/developerguide/authorization-endpoint.html
Easy enough I think, just have to change the checkAuth handler.
Probably if we keep thinking we'll find some other options too.
from cloudfront-authorization-at-edge.
I don't want to turn this into a support issue, but do you happen to see what I'm doing wrong here. I added the idp_identifier code, and passing it to /authorize.... and I'm getting back: ERROR: Error: [Cognito] invalid_request: invalid_scope
This is an example of the URL I'm sending, can you see anything wrong: (I decoded it to clean it up for you, but its encoded when sent to the server):
redirect_uri=https://d2tbgx16w63u2h.cloudfront.net/parseauth&response_type=code&client_id=123d4ml5pj67n8f9rmupcllelr&state=eyRub25jZSI6IlF1QXg4TmduQVJ5ZGAMEjciLCOyZXF1ZCK0ZWRVcmkiOiIvP2lkcF9pZGVudGlmaWVyPWNsZWFyLW9rdGEtaWRlbnRpZmllciJ9&scope=phone email profile openid aws.cognito.signin.user.admin&code_challenge_method=S256&code_challenge=8Y4W_eYh7cH-ihCA7ZV4uXb8ApOe9tArTfAM1xMOUI4&idp_identifier=okta-identifier
from cloudfront-authorization-at-edge.
The URI looks good to me. Did you also allow all those scope on the User Pool client?
You URL encoded you mean, to clean it up? So it was something like this before? "&scope=phone%20email%20profile%20openid%20aws.cognito.signin.user.admin&..."
That should be good.
from cloudfront-authorization-at-edge.
Great to hear!
Will close this issue for now, don't hesitate to report back if you run into anything else.
from cloudfront-authorization-at-edge.
Wait, still have to improve the error message.
from cloudfront-authorization-at-edge.
Added nicer err msg in #48
from cloudfront-authorization-at-edge.
Related Issues (20)
- Refresh issue after token expires HOT 8
- On signout Required String parameter 'redirect_uri' is not present HOT 5
- Possible Open Redirect (CWE-601) in sample code HOT 2
- nonce cookies are not expired HOT 1
- [Feature request] Support multiple Cognito user pool clients HOT 4
- custom domain is not redirecting to cognito hosted ui HOT 1
- Getting blocked by CORS policy but unable to figure out the source HOT 5
- Node version bump HOT 7
- Custom IDP with Amplify and Auth at Edge HOT 9
- Fail on delete of the stack HOT 3
- Function must be in an Active state error on deploying the solution HOT 7
- Errors from Lambda when destroiyng the stack HOT 2
- Cognito TAGS HOT 1
- How Do I add User Pool attributes to Cookies? HOT 1
- A potential risk in cloudfront-authorization-at-edge which can be used to upload malicious code. HOT 4
- Having the ability to tune logs HOT 1
- Deployment to eu-west-2 fails with error: Encountered a permissions error performing a tagging operation HOT 4
- Missing User-Agent header in Post request to cognito HOT 4
- Question: redirecting after download from S3 HOT 2
- 'JavaScript heap out of memory' when running npm run build HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cloudfront-authorization-at-edge.