I am using AWS Cognito for authentication in my application. Cognito provides fully client-side authentication. But, we need to store credentials in .env file which is accessible from the browser.
Is it secure to use AWS Cognito for authentication, if I am building an enterprise application and security is important for me?
For AWS cognito the authentication happens at server side. Not on the client side. At the client side we are creating the opportunity for the user to log via his credentials, then the credentials will be sent to AWS Cognito for authentication. Which results in a accept or reject.
Cognito itself is a service that you can build a secure identity foundation on - but not in the way you're proposing it.
Storing static credentials to 3rd party APIs in something that can be easily accessed by (un)authenticated users is a terrible security practice.
The security of Cognito is not your biggest problem, my advice would be to first find a better solution for your static credentials. Sometimes static credentials like API keys can't be avoided, but you should never expose them to your end users. Store them in something like the AWS Secrets Manager or the Systems Manager Parameter Store and retrieve them when you need them. Only store them in memory if possible and never send them to your clients.
Related
I have an AWS REST API Gateway with Cognito authentication using the client credentials grant.
We have been creating new clients by hand and sharing the ID/secret with people who need to use our API. They send the ID/secret and "grant_type=client_credentials" to Cognito, it gives them a bearer token and they use the API with the token. All fine so far. (It is a CLI tool running on a schedule, not accessed by a browser. I specifically need to avoid any sort of "go to the browser to login".)
Now, we have a new "island" of users who have a local OIDC (Azure AD) provider that can issue them a bearer token from a curl to an endpoint.
Is there a way to make Cognito accept those tokens??
I have tried federating Cognito with a different oidc provider (I don't have AD, but a different provider), getting myself a bearer token from it and sending it to the API GW, and I just get 401'ed. I don't know if there is something I'm doing wrong or if it's not possible.
(Things I might be doing wrong seems to be a long list! I need to create a client in the other provider and add it's ID/secret/URL to Cognito, that works. I used the same client ID/secret to generate my bearer token. But when I'm in client creds flow in Cognito, I need to set a custom scope. Do I need to add that scope to my initial request to the other provider (The API GW doesn't require a scope, it is just a mock endpoint at the moment in testing). The client_id= in the request is for the client in the other provider, not the Cognito client ID. Should I set it to the Cognito client ID?)
OR do I need to write a custom authenticator for the API GW to validate the token? (Decode JWT, Check : issuer is allowed and signature is valid.)
And not use Cognito at all for these other users.
(If it was an HTTP API, I think I can create a JWT authoriser and it does it all for me, but it isn't and there are some features on REST APIs not available on HTTP (like WAF))
Sorry it's a bit short on details. I could spend days copy/pasting all the configs from ID provider/Cognito but if it fundamentally won't work I wasted my time!
(After trying it, I think maybe federation only works for actual users with a browser based login flow, not clients with a CLI flow. I can't find anyone saying client credentials flow does work anyway!)
Cognito is using the authorization server role. So in all cases, the tokens returned to client applications will be issued by Cognito. These apps will never deal with Azure AD tokens. Multiple types of client can coexist together:
CLIENT CREDENTIALS GRANT
Clients who use this flow might represent B2B connections. The business partner must always get Cognito tokens directly, and no federation is used here.
AUTHORIZATION CODE GRANT
Browser clients will use this flow, and you can configure Cognito to implement authentication by making a second OIDC Connect redirect to Azure AD.
My blog post provides a walkthrough on how settings are configured. Cognito will act as a client of Azure AD and use a scope such as openid profile email.
After a user login, Cognito will receive Azure AD tokens, validate them, then issue its own tokens. Nothing will change in the API gateway, which will continue to verify Cognito tokens.
I am trying to understand which authentication suits good for Azure Function app because I have to expose function app end point to external team.
I have enable Azure AD authentication and planning to share App registration client_id and client_secret (endpoint oauth2/v2.0/token) where they will generate bearer token to Authenticate and consume my endpoint.
I was wondering if there is any other best approach of authentication than Azure-AD because I am exposing to external team.
Please assist, Thank you.
the most secure option is to request access tokens trough the Azuthorization Grant Flow with PKCE. No secret is required, however if you need to use one, we recommend using certificate credentials which are asymmetric thus the exposure of the secret is more and better controlled.
You can also, configure token and enforce additional security measures trough Conditional Access policies. With them you can configure session lifetimes, require MFA for selected or all external users that access your application, that they authenticate from a compliant device, well known IP range or location, and more.
Also, and at the PAAS level, you can Set up Azure App Service access restrictions.
I have two web applications app.domain1.com which is a SPA with his own API on api.domain1.com and app.domain2.com) with each have their own authentication system and user accounts
and I need to authenticate the user from app.domain1.com from app.domain2.com. The goal is to simplify switching from one app to another without requiring the user to log into each application by re-entering their password. I'm the owner of one app only so It's not possible to put them behind a reverse proxy or so.
Example :
app.domain2.com redirect to app.domain1.com/connect/{JWT} -> app.domain1.com SPA extract the JWT and send it via ajax to api.domain1.com for validation and login.
I have looking for OAuth2 and OpenID Connect for these but OAuth2 is more about delegation of resource access than authentication and OpenID Connect needs an Identity Provider which seems incompatible with my use case where each app has his own authentication mecanism and where I could not add a central authentication server.
Ideally, I'd like to adhere to a standard protocol.
I thought I could expose an endpoint GET /connect/{JWT} on each app.
The JWT could contains an email which could identify the user account, app.domain1.com and app.domain2.com could then share the secret for validating the JWT has not be tampered
and could have a short validity duration.
This endpoint validate the JWT, verify if a user match the email inside the JWT and log the user in.
I'm not sure about the security considerations with these process and if there is any other options ?
Thx for your help.
In my opinion you should go with OIDC. That protocol is designed exactly for the feature you described here. You can have one of the apps act as the IdP, and the other will be a Relying Party. It depends on which technology you use for your apps, but in some languages there are libraries which will turn your app into an IdP.
You can think of some generic protocol to make that federated login work, but you will be better off using standards. This way you won't have to wonder what are the security implications for your solution - you have security considerations for OIDC described in the spec itself.
I'm trying to setup an application to validate identity using Azure AD and acquire a token to allow access to a secure api. The front end application is written in angular and allows anonymous access. What can I use to access AAD authenticate and return an access token?
This will be an angular 6+ UI that is communicating to a secure .Net api using Azure AD for authentication. I have done a couple days research and everything points to a user logging in to authenticate using the login page. I need it to be by app and open the login page. I tried a couple examples where it utilized authentication/authorization and that didn't work because the app needs to authorization the user to talk to the api. I have seen where people were using Microsoft graph but once again it was user based and they were redirected to an azure login. I am looking for a solution that will allow me to setup an account in azure ad and authenticate the app on start to get an access token to allow communication to my secure api. If I have missed something somewhere in my research and test attempts let me know. This is my first Azure AD auth attempt and I feel like I am missing something for application authorization.
The problem is an Angular app is what we call a public client.
It cannot hold secrets and thus cannot prove its identity.
So, only user-based authentication flows should be used by public clients.
Confidential clients on the other hand can hold secrets as they run on servers that you control.
So for example, a back-end Web application or API would be a confidential client.
Those can use the client credentials flow to acquire access tokens and call APIs as themselves without a user being involved.
There is a bit of a fundamental issue in your question.
Your API requires authentication, but you want functionality to be available to anonymous users.
So you want to bypass authentication.
If you really want to bypass authentication for parts of the API, you could just make those endpoints available anonymously without a token.
I'm building a SPA (angular) with a back-end api (asp.net core), both are build and belong to the same party.
I would like to use jwt authentication instead of cookie based authentication, because both sides - the back-end and the front-end spa - are owned by the same party I'm thinking to use the OAuth Resource Owner Password Grant flow and there shouldn't be any problem exposing the users credentials to the web app.
After searching on the web, I see a lot that it's not recommended to use this flow, but why should I implement any OpenId Connect flow with a redirection to the auth server if the web client belongs to same party of the api and the auth server?
The problem in your case is not so much in exposing the credentials to the Client since as you mention, all components in the flow are controlled by the same party.
Yet there are advantages to redirection as doing so separates the authentication method and means from the Client itself. And that enables e.g.:
a change of authentication mechanism or an upgrade to multi-factor (or some other advanced form of) authentication without impacting the Client(s)
SSO across different web applications
granular per-Client permissions
easy access revocation without having to change the user's password
less confusion for end-users as to which applications(s)/Client(s) they can trust with their credentials