Link a third party application account in Cognito - node.js

I need to link a third party application credentials to the one the user uses to connect to my application through Cognito. In other words: user connects to application A (my application), then application A asks user for credentials to connect to application B. Application A then interact with application B with the credentials provided by the user. I would like to link those identities but let the user connect to application A only with credentials I provided him (and not from the ones he uses for B).
AWS has AdminLinkProviderForUser in Cognito which doesn't satisfy the last requirement.
Application B offers multiple authentications: Form, Basic HTTP, SSO, OAuth2 and OpenID.
Is there any way to link the two identities in the way described above and store it in Cognito for future use?

If I am understanding you correctly - what you need is for the user to log into your application with credentials they have for another application and then store the login they have for that application and provide them with new login details where those login details link them to your application and the that application.
Have a look here: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html
However taking that approach the users will still login with application B details. But Cognito provides that out of the box.
If for some reason you do not want to take that approach - and you want to have a force change on the password you must do the link yourself.
A suggested approach would be as follows (Making use of Lambda Triggers in Cognito User Pools):
Pre-signup lambda trigger:
Get the user credentials
Use the credentials to make the call in that lambda function to
application B.
Get the authentication response from that call
Pass this as a param to your Cognito user attributes
Make a call using AdminCreateUser(https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminCreateUser.html)
Now you have the user stored with the auth data from application B as a custom attribute.
This is not the best way to do it though because auth data usually needs to get refreshed which will add extra complexity. You could do that refresh in a Pre-Authentication Trigger that updates that custom attribute for the user.
Honestly, if application B is custom, I think the best approach for you will be to use OIDC Provider approach https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-oidc-idp.html

Related

Login App with IdentityServer4

I have to develop a SSO system and I have to do it using IdentityServer4. I have gone through the documentation and examples but I have some doubts. To be honest I don't quite get it, but I am really new in Oauth2 and OpenId Connect.
We will have a bunch of clients (web apps), each of one of those will have their own Web APi. And we have to have a centraliced Login App for all of those. I think the example with the javascript client is the closes to the thing we want to achieve. Also, a user might have permission to access one client (app), but not another, so the IdentityServer must provide information about wich clients (apps), that particularly user can access.
So, These are the things I don Understand:
1.- In the documentation I can read there are two tokens, an Identity Token and Access token. But in the examples all I see are the access tokens. It seems to me that the access token is the one with all de info needed. am I wrong?
2.- Also, I have read about de Grant Types and I'am not quite sure wich one we must use. At first I thought to use the ResourceOwner password, because it requires the client, the secret, a user and a password, wich I assumed it could be the end user. I found this example http://sunilrav.com/post/How-to-Customize-Authentication-in-Identity-Server-4 were one could customise the class that validate the user and password. I thought that this could be the way to go but the documentation statesa about this grant type "...This is so called “non-interactive” authentication and is generally not recommended.". The javascript client example uses the implicit Grat type, wich the documentation states is for browser-based applications (our client apps will all be browser based using react).
3.- can my Login app be a Javascript (react) app? The example Quickstart is made in MVC.NET. This login app connects directly to de IS4 server without asking for a access token? (In the example the app is embebed in the IS4).
4.- Can I protect with IS4 a WEB API which is developed in .net framework (4.6.2) and not in .Net Core? I havent Found Any examples.
the documentatios I followed is the offcial. The examples (quickstart) are also there. (I can't post more than two links).
thank you very much for reading and for your help.
Identity Token and Access token
Identity token is the one that contains the identity of the user, that will tell the client app that what user it is. After successful login, user will be redirected to the client app with these tokens. Response will also have claims, such as permission scopes, name , email you can add custom claims as well.
Access token is used to access your protected web api resource. You have to send the access token with each request to access the api.
Grant Types
Grant types is basically how you want your client app to interact with the auth server. https://identityserver4.readthedocs.io/en/release/topics/grant_types.html
can my Login app be a Javascript (react) app? Your client app can be a javascript app but your auth server that is the identity server which will have the login/signup pages(and other login jazz) and account controllers should be you MVC app. As, everything is already done using MVC and Entity framework, why you want to re do everything.
Can I protect with IS4 a WEB API I am not sure about this one, but I dont see why you would not be able to do it.
This is a good answer for basic IdSrv flow!
UPDATE In my understanding, the answer to which Grant Type to use it depends on your client application requirement. If you want to use a Javascript client you can use Implicit Flow, but you won't be able to use refresh tokens and your access token is not 100% secured with the browser as client can access it.
If you want to open your web api to public then you can use client credentials flow. If you want to be more secure you should use Hybrid flow or HybridClient credential flow. ( again depends on the requirements ). with this you will be able to use refresh tokens and in this way your access token would be more secure.

AWS - Cognito Identity with nodejs - What to do with tokens

So I'm trying to use Cognito Identity in my nodejs API. My goal in using Cognity Identity is to be able to give users a secure way to create a user account and log in. I'd like to use my API to make aws cognito calls to verify users by identifying them with their email address. My API will then give users access based on who they are, which is based on their email.
I was able to create a user, verify the user's email, and log in to get an AccessToken, IDToken, and RefreshToken. That's great, but at this point I'm not entirely sure what to do with these tokens. I'd imagine I can somehow use them to verify a user every time they make a call to my API, but I'm uncertain how to do that.
I'm imagining authentication flow going something like this:
User logs in with their password -> My API makes a call to aws to get tokens -> My API passes those tokens back to the user's mobile device -> Their mobile device stores these tokens -> AccessToken is used to verify all API calls until it expires -> RefreshToken is used to get a new set of tokens if AccessToken expires -> If RefreshToken is expired user must log in with username/password again.
Is that incorrect or an improper way of doing this? If I have the right idea, then how do I use the tokens to accomplish this? I wasn't able to find any documentation on the authentication process once a user gets their tokens. The only thing I can find that seems it might be able to accomplish this is here: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#initiateAuth-property
Your next step depends on what service you use and how you use it.
For example, for an API-driven application with Lambda / API Gateway, you'd use Amazon Cognito User Pools for your API resource methods and send the ID token as an Authorization header with your API call. (Yes, the name is misleading. It should be Authentication since the authorization logic is actually implemented in your Lambda function)
Then, your Lambda function can access the identity claim properties from the user pool using the context object (when you enable Lambda proxy integration) as:
const email = context.authorizer.claims.email;
or
const cognitoGroups = context.authorizer.claims['cognito:groups'];
If you haven't enabled Lambda proxy integration, you should make sure to pass those values in your body-mapping template.
You can find code examples here and here.
There is a good reference github application that demonstrates various aspects of cognito and how integrates with lambda, API Gateway, DynamoDB and other AWS services.
Here's a link:
https://github.com/awslabs/aws-serverless-auth-reference-app

How to secure an API when the consumer uses claims authentication

Background
I'm building a .NET MVC enterprise web application that must have the ability to authenticate users from different companies. One of the major requirements was to ensure that users don't need to create and remember new credentials to use the application, instead they should continue to use whatever credentials they use to access applications within their company intranet.
Since the application will be hosted on the extranet and needs to handle authenticating against multiple domains (i.e. multiple Active Directories), we are expecting each client to set up a security token service (AD FS) that the application can interface with to implement claims authentication.
The MVC application will check if the user is authenticated, and if not, start the workflow that ends with the MVC application being given a SAML claim being associated with the user.
Problem
At this point, the user is authenticated and given access to the MVC application. However, the application itself is a modern day web application that uses quite a bit of JavaScript to consume a .NET Web API that handles most of the business logic. My main question is how I can secure this API. I want to make sure the only requests being sent to this server are being sent from a valid source, and that the user consuming the service has permissions to do so.
Current Solutions
There are two approaches I can take to consume the API:
Straight from JavaScript (Preferred solution)
Route the request through the MVC server, which will then forward it to the API.
In order to pick an approach, I first need to find a way to secure the API.
HMAC Authentication
The most straight forward solution I've found is HMAC Authentication - http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/. However, this approach requires all API requests to come directly from the MVC server, since the secret key will need to sit on the MVC server.
OAuth 2.0
The second approach I can implement is some flavor of OAuth 2.0. The flavors I'm familiar with can be found here http://alexbilbie.com/guide-to-oauth-2-grants/:
Authorization Code
Implicit
Resource owner credentials
Client credentials
Authorization Code Grant
This is not the approach that I want to take. The MVC application has already received claims for the user - they shouldn't have to do it again just because the API needs the claim. (I have a followup question asking if I can simply pass the claim to the API server)
Implicit Grant
I like the way this approach sounds, since I will be able to execute API requests in the client (i.e. JavaScript code), however it suffers from the same problem as the first approach.
Resource Owner Credentials Grant
This approach is out of the question - I don't want either the MVC application or the API to ever hold onto the user's credentials.
Client Credentials Grant
This approach is the only reasonable OAuth approach listed - however I fail to see a major difference between this approach and HMAC authentication detailed above.
Questions
Have I correctly set up the MVC application's authentication structure? Specifically, in this context is it appropriate to have AD FS handle authentication and respond with SAML tokens representing user claims?
I plan to store user data in the server's session. Can I also store the user's claim in the session, and then somehow send that up to the API for authentication?
If I can pass the claim from the MVC server to the API server, and the API server can correctly authenticate the request, is it safe to pass the claim to the client (browser / JS code) so that consuming the API can bypass the MVC server?
Is the HMAC Authentication approach the best way to go?
Yes, using ADFS or any IdP products as an IdP for your application is a good way to implement SSO. Doing this way help you delegate all the federated access management as well as claim rules to ADFS.
Yes, you can store claims in session and somehow send them to the WebAPI. Please note that if you are using WIF, it already stores claims in Thread.CurrentPrincipal as a ClaimsPrincipal object. Another thing is that I assume you only want to somehow send the claims only, not the whole SAML2 token.
I would say it is as safe as the mechanism you use to protect the token on the client side. Check https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/ and https://security.stackexchange.com/questions/80727/best-place-to-store-authentication-tokens-client-side for more details.
I can't say if it is best for you, but it seems to be a viable way, given that you have control over the WebAPI too. However, it also seems that using JWT token would be easier: https://vosseburchttechblog.azurewebsites.net/index.php/2015/09/19/generating-and-consuming-json-web-tokens-with-net/. Talking about JWT token, you can also ask ADFS to issue it for you: https://blogs.technet.microsoft.com/maheshu/2015/05/26/json-web-token-jwt-support-in-adfs/.

Building a Web-API with Oauth2/OpenID connect

I'm trying to understand conceptually and practically how to perform an oauth2 with openID-connect flow in my web-api application, utilising Azure AD.
Importantly, when a request is made to the API I want to know who made the request.
My current understanding is :-
My client would detect that the user isn't logged in and redirect to a sign-in.
The user would provide their credentials, and be redirected back to the client, along with an oauth2 token.
This token would be supplied to web-api endpoints for any requests.
This is where it gets murky for me.
How exactly do I use this token to authorize access to a particular resource, determine who is accessing the resource, and what is the mechanism that does so?
I'm sort of assuming that I would need to reuse the token to make a call to the Azure AD user endpoint - if the token was indeed valid, the AD endpoint would return the users details - thereby providing some means of determining that the token is valid and providing details on the users identity. Authorizing access to a resource could be done through membership of groups in Azure AD.
BUT ...
I can only assume this a solved problem, and have noticed use of OWIN middleware as per this example
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
But I'm still rather unsure as to what is exactly going on.
The service makes mention of scopes and claims, but I don't understand where these are derived from (I assume from a token supplied by the client, but not sure). The service must be receiving identity information in the call.
Which brings me to two points, for this to be secure -
The token provided in call to the service would need to be secured in transmission (hence the use of HTTPS) - to prevent MITM.
The token would need to be signed some how - I guess by using client secret or something - to prevent information in the token being spoofed.
Can someone help me clear up this muddled mess?
In particular -
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
How to limit access to some endpoints of the API based on a user role?
What do I do to practically achieve this by building on existing middleware and libraries available to me?
Disclaimer: This will not be a comprehensive answer. It is off the top of my head.
OpenID Connect provides an identity layer on top of OAuth. In your case, Active Directory provides the authentication and sends back an access_token. The access token represents a user that AD has authenticated. If your doing OpenID Connect, then AD will also send an id_token, which may contain additional identity information (such as birthday, avatar, and whatever else AD exposes.)
Neither OpenID Connect nor Active Directory have anything to do with the the roles that your app assigns to a user; roles are entirely the bailiwick of your app. You assign user roles just like you normally would; you assign them to the nameid though instead of to an email address or username. Your app no longer has to authenticate the user but it does need to assign roles to the nameid.
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
The identity is embedded in the access_token that AD includes in its response. This token will have a nameid in it that your app can associate with a user and role. The nameid is like an email address, username, or other uniqueID that your app uses to recognize the user.
How to limit access to some endpoints of the API based on a user role?
You choose. When your app receives a request with a particular access_token, that token will be associated with a particular user via its nameid, and you can assign whatever roles and rights to that user. Basically, associate roles with a nameid.
What do I do to practically achieve this by building on existing middleware and libraries available to me?
There is an unfinished demo here, though it doesn't use Active Directory as the provider, instead, it uses an internal provider. For the demo, the username is shaun and password is Testing123!. The source code is here.
Here is the link to the source of another demo, though again, it doesn't use Active Directory as the provider, instead, it uses Twitter.
The nice thing about OAuth and OpenID Connect is that we can use whatever identity provider we want, so you can adapt the demos to use Active Directory.
Apart from question #1 (the identity is verified on the service side) all your question are very open ended and would require a super long answer.
I would recommend reading https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/ - it is a good introduction to the flows underlying many of the modern authentication cenarios, including the web API one you are focusing on.
Once you have read that, you will find a complete set of samples in https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/ - in particular, I suggest studying the web API and thru authorization one to find guidance on the 3 questions you listed. HTH!

OAuth authentication and consumer secrets

I have a webservice which acts as backend for smartphone apps.
I want to be able to authenticate users as painless as possible, but even though I thought I understood the OAuth I must admit there are some missing pieces here and there.
Authentication:
Let's say the user has an Android phone. He is probably already Authenticated to Google and it would be really nice if I could just extend this authentication to my webservice. Android has OAuth support so the users opens his app, grants permissions to use his google account and the app authenticates him to the web service.
Web service
Since the service should accept users from all kinds of devices it should not be Google specific. It should be possible to register an account and login from any device. I'm unsure if it is possible to register a new account with OAuth alone or if you need some other kind of authentication first - OpenID for instance.
How would the flow be for the generic webservice? A generic API for registering a user and granting him access to an API?
Furthermore - I do not want to control the devices connecting to this service. I can see OAuth requires a consumer_key and a consumer_secret. If I run everything through SSL - is the consumer secret still secret or can I just use some dummy values? Thus avoiding creating a device-registration system where people can acquire a consumer_secret?
For your case, if you want to use Google/Facebook etc as authentication providers, you will need to use the 'Authorization Code' flow of Oauth2. In this case, you register with Google/FB as a developer and get a client id and secret for using their API.
Then you obtain the Login with Google/Facebook button and code, which you will use to fire a "webview" or an embedded browser where the user will be taken to google/facebook and asked to provide his login credentials.
Upon success, an authorization code will be sent to a redirect url that you would have provided while registering as a developer at Google/Facebook. You will need to catch this authorization code and then again call the relevant API to obtain the access token, which you can then use to fetch the user's details to register him in case of first time or authenticate him if he's already registered through this method earlier.

Resources