I am in the process of building an microservice architecture with an angular frontend as ui component. Each microservice uses flask-restx and pycognito to secure its routes. The frontend uses aws-amplify to authenticate users. Each microservice expects a valid token for the secured routes, which is validated in the respective backend. In the aws user pool we created multiple app clients. The goal is to authenticate once against the webapp and use the token to access all microservice backend. I already tried to find the correct solution in the aws documentation but had no luck until now. Maybe somebody could give me a hint what is the best practice solution to get this done right.
Keep it simple and stupid (KISS).
I cannot see any use-case of multiple app clients.
Please follow the steps below at microservices end:
Cognito uses asymmetric keys to generate jwt token.
So, get the public key from Cognito by this code link.
Decode that jwt token by public key link.
Authentication will be done by above step. if invalid token is passed in request header jwt.decode function will raise exception link.
Decoded payload contains sub and store that sub in distributed db (dynamodb, SQL)
One can store custom attributes and assign Cognito user to group. This will help to authorize the individual users on the microservice side.
I hope that gives you a hint to go ahead.
Related
MY goal is to setup the Cognito Hosted UI to validate users after login. I have followed the steps laid out in the OAuth2 blog here: https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type
My steps are as follows.
User logs into the AWS provided login screen.
It redirects to my website and I pull down the authorization code in Angular.
I send the code as part of my headers to the backend Nodejs
I use the code to get a token and then validate the token
This stream works but then what? I want to validate the AWS token for each API call but I have no idea how to access the token.
I am guessing that I am either missing the point of this procedure or that the token is somewhere I am unaware of.
Any help would be greatly appreciated.
Usually you have your own UI that redirects to Cognito to authenticate, after which the UI sends the access token to the API on every request.
All of the code samples on my Quick Start Page work like this and use Cognito.
If it helps, this is what the OAuth Technical Messages look like. Feel free to ask any follow up questions
I have my web application. Now i want to integrate salesforce into my web app so that i can push data from my app to any salesforce org after the authentication(OAuth).
I found 2 ways:
1. Connected Apps
2. via wsdl generation file and use
I created a connected app from my developer account and i authenticated using consumer key, cusumer secret key(from my connected app) and username of user and secret token of the user account.
I tried with another free trail account, It's validating and fetching the details and post data also working.
My question is, shall i deploy my connected app into app exchange, then only i caan use REST APIs ?
generating wsdl and coding around is the better option than the above ?
Is there a option, only one time authentication enough for any number of sessions and use the REST APIs?
Please suggest me a best way to proceed.
You're mixing up a couple of independent issues here.
If you're going to authenticate via OAuth, you must have a Connected App.
A SOAP API login() call requires you to store a username and password, which is undesirable.
There is no way to "permanently" authenticate, i.e., to get a session id that never expires. Your app must always be ready to get a new access token via the OAuth refresh token it obtains and stores (via, for example, the Web Server OAuth flow), or to reauthenticate via JWT flow.
Connected Apps are global metadata in most cases. You don't need to deploy a Connected App into a target org in order to authenticate using its Client Id and Secret into that org. The only exception I'm aware of is if you want to use the JWT flow with a certificate and preauthorized Profiles and Permission Sets.
Based on what you've shared, I don't see any reason for the AppExchange to be involved.
Is it possible to use AWS Cognito User Pools as an authentication and authorisation provider for a Spring Boot app running in EC2?
The user pools seem to provide a lot of the regsiter/login/email/forgotpassword etc plumbing, that I can make use of in an AngularJS front end.
If the front end does all the auth (in javascript), can a java (spring) backend verify tokens passed to it from the front end, and if so how?
Or, can/should the calls to Cognito come from the backend, and again, if so how? Do I need to use the AWS Android mobile SDK?
(I've looked at Lambdas and Api Gateways but they are not what I am after at the moment).
Either one of those options should work, depending a bit on your app requirements. The former does have the benefit of sending user credentials over the wire less often than the latter.
If you want to verify the tokens with your first suggestion, you could do one of a few things. Cognito vends an id token, a refresh token, and an access token upon a user authenticating. Any call that takes an access token (i.e. GetUser) does validation on that access token. Alternatively, you could make a call to refresh the tokens, which will do validation on the refresh token. More information on the tokens Cognito vends is available here. Token refreshing is done through the Cognito auth flow, using challenge name REFRESH_TOKEN or REFRESH_TOKEN_AUTH.
If you opt to go with the second one, AWS does have multiple SDKs for various languages, including Java. These all support the Cognito APIs, but Cognito does use SRP to sign users in. The client side calculations are fairly complex, so you might not want to take that on yourself. You could rip our calculations from the SDK on Github, or you could use the admin no SRP flow described here.
I have a Django application that currently stores user credentials and performs authorization and authentication. I am in the process of breaking off the front-end into an Angular SPA and converting the backend to a REST API. My Django API will live as an Azure API app protected by Azure API Gateway. I would like to remove the authentication piece from Django and allow users to sign in using OpenID Connect through either Google or Microsoft Account. What I would like to happen is this:
When a user visits the site, assuming they have never registered with my app, they will have the option to sign in with their Google account or Microsoft Account. If the user decides to sign in using their Google or Microsoft account, (this is where I'm confused and why i'm posting here ... ) I think what happens is the API Gateway performs the authentication, generates a JSON Web Token (JWT), and sends that token back to the Django API. Django receives the JWT, decrypts it, and checks to see if there is a user account matching the email address in the JWT. If there is not a user account, Django will add a user to the user accounts table (not storing a password). If there is a user matching that email address, then Django allows the user in.
All that said, I guess my question(s) are:
Should I do the authentication at the API Management Gateway or should I do it at the Azure Web API?
Can I use Django's built-in authentication system to do what I want or is that not needed?
Am I over-complicating all of this? Is there an easier way to do this? All this seems like a lot of work.
Is OpenID Connect what I should be using (instead of Oauth2)? I have no experience with either.
Azure API Management does not actually provide any kind of JWT issuing mechanism, so you'll have to implement that yourself. The end points for doing that may or may not be exposed via API management.
What possibly gets you confused is the fact that the APIm Portal supports various indentity providers, like Twitter or Google, to sign up for the API. But these are not your application users, these are for the API Portal Users.
What you can do with the APIm Gateway is to validate subsequent calls to your backend API that the supplied JWT token is valid (using the <validate-jwt> policy).
Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).