We are evaluating an option if the "same" azure AAD access token be used to access multiple webapis.
Here is the flow :
Client -> webapi1 -> webapi2
1) client authenticates against AAD and acquires token1 <br>
2) client calls webapi1 with token1<br>
3) webapi1 calls webapi2 with token1
Lets say both the webapi's are configured to validate the same audience ('xxxx') and authority, are there any complications/security issue to leverage the same token for both the apis.
Any input is much appreciated.
In that case webapi1 and webapi2 are essentially the same API as far as Azure AD is concerned.
One con of this approach is possibly too many privileges on the APIs.
Let's say API A requires access to all users' emails in the organization. Now since API B is effectively the same app from AAD's point of view, it also gets this right, though it didn't need it.
Typically we try to follow the principle of least privilege, where every part of the app has exactly the access it needs, and no more. So using the same audience again can go against this.
Another issue is that another app which has rights to call API A also gets rights to call API B.
I can understand your reasoning for avoiding the round trip of fetching an additional token, but tokens can be cached.
Related
I have a service that will be registered in Azure AD as an App. It will have one app registration per region (West US, East US, etc.). Clients calling this service need to acquire an access token. The audience of the access token MUST be the corresponding service for the region. The services are segregated regionally so that an access token for a service in one region cannot be used to access the service in another region. This is by design.
Is there a proper way/recommended best practice for the application discovery?
I have explored the idea of using Graph API. In the model:
Each of the registered services will be created using a templatized naming convention e.g. -. There is a concern here that without proper coordination within the tenant where these apps are being registered, we could end up with a name collision.
A “discovery app” (application registered for the sole purpose of usage for discovery) will have Application.Read permission the Graph API. Authentication here will be based on a X509 certificate for greater security.
Using an access token acquired against the discovery app, Client will query Graph API for the intended service app audience matching on the name. Once that app info is obtained, we’ll have the service app id. Again, concern from #1 above still stands - another application registered with same name will also be found.
Client will then use service app id obtained to acquire an access token to talk to the service.
Any help/direction would be much appreciated. Want to make sure I am not re-inventing the wheel if there is already an appropriate pattern to doing this.
Your design is feasible. Of course, you need to make reasonable adjustments to the names of app registrations to eliminate the influence of name collision.
I have a suggestion that you could add these service app registrations into a security group and use Microsoft Graph (Beta version) to list them with a filter (templatized naming convention).
Reference here:
GET https://graph.microsoft.com/beta/groups/{id}/members?$count=true&$filter=startswith(displayName, 'a')
ConsistencyLevel: eventual
Please note that $count=true and request header ConsistencyLevel: eventual is necessary.
There is a property appId in the response which is what you need. In this way, the influence of name collision can be avoided as much as possible.
I have 3 microservices that hold particular user information including their sign-in credentials (email + password). If the services are A, B, and C then the user "John" will have his info stored separately in all three of these services' database.
Now, the user info in service A is updated at an earlier point of time, and at that moment it is not predictable whether services B or C will definitely be activated to be used by that particular user. So, there is no point in creating an entry in B and C for "John". But, as "John" activates B or C at a later point of time, the system can only have access to the hashed password.
It is to be noted that the service C requires the password to be stored in encrypted form so that it can be decrypted later. So, merely storing the hashed value in all 3 services is not feasible, neither do we want all 3 of them to have encrypted password.
What is a feasible solution to sync the password between the services by maintaining the requirements?
Your approach implies a lot of problems in addition to the one you already described yourself. I recommend to look into Federated Identity (using OAuth2 and OpenID Connect) which fits for Microservices architectures.
Basically, this means that authentication and credentials handling is performed by a separate highly available and scalable service (usually referred to as identity provider or authorization server) that only does that - handling user credentials, identity and access control - and does it well.
It handles login and issues access tokens which are then sent to your Microservices along with the requests. As each Microservice will trust this identity provider it will be able to verify that the token is valid and was issued by this identity provider (this happens by validating the token with a public key). And the token contains information like user id and information about what actions are allowed with this token.
The identity provider can be a cloud service like Okta, Auth0, Azure AD B2C, etc. (see https://openid.net/developers/certified/#OPServices) or host an identity provider on your own, if you are not able to access cloud services, by using ready-to-use libraries available for your technology stack (https://openid.net/developers/certified/#OPLibs).
So there is no need to store user credentials in each Microservice and sync this information between them. I would consider such an approach as an anti-pattern.
The federated authentication approach also allows to solve other problems such as single-sign-on.
If you are new to that topic it can be a little overwhelming at first but it's something you can't get around if you really want to have all the advantages a Microservices architecture can provide.
This article might help you get started:
https://nordicapis.com/how-to-control-user-identity-within-microservices/
In one of my Projects i need to implement Login Step-up. That means a user can login an application with simple username and password to get some readonly access access on website and API behind it.
If user want to performan any sensetive data operations like "write/update", he need to authenticate via second factor (via SMS code).
second factor login is for maximum 10 minutes valid, if user does not interect the website for 10 minuets, he will be automatically logout from second factor, but he still remain logged in with one factor.
can identityserver4 support this szenario out of the box? or do i need to implement it by my own ?
Here is my solution proposal:
for one factor login, identityserver provide a one factor scope, which client need to understand. it provide a access token which also have limited scope.
when client application need two factor scope, it call identityserver again where user must provide second factor authentication. hence a new token with second factor scope sent back to client. with this token client can call API methodes which need second factor authentication.
second factor authentication token has a validity of 10 minutes
after 10 min token is invalid, but one factor token is still valid as it has long life time.
Questions:
- Can IdentityServer4 offer Login Step-up out-of-box? if no, what are the alternative solutions ?
what is your suggesstion regarding my solution proposal?
Thanks in Advance
What you wrote in the bullet points is basically how I'd see it implemented in IdentityServer4. It's just setting up two different scopes and issuing two separate tokens for the same user. First scope 'readonly', lifetime=24h, acceptable only by safe operations in the application api, second scope 'full' with lifetime=10mins acceptable by all operations. No big problem, it should be perfectly doable with basic IdentityServer4. However, you will have to RT(F)M and configure the scopes, clients, tokens, etc. in the IdentityServer4 config. And also, you'll have to implement the two-token access policies in your app's backend api implementation, and of course client apps will have to be careful about which token they obtain and which token they use for which backend call.. but all of that is more-or-less obvious (and you seem to understand that, judging from that bullet points) so I don't quite see what you'd want by saying "out of the box" or what are you worried about in terms of support for that on the IdentityServer4 side..
I want to have an architecture made up of these devices / programs with different roles (which are all separated, none of these roles must exist in one and the same instance):
CLIENT
AUTHENTICATION-SERVER
AUTHORIZATION-SERVER (there can be a multitude of these)
RESOURCE-SERVER (also many possible)
And:
I don't want to use any websites a user has to navigate to.
From my studies of OAuth and Open ID Connect I would assume that a Client could get an ID_TOKEN (after authorization) from an AUTHENTICATION-SERVER and could then request ACCESS_TOKENS to different resources from the AUTHORIZATION-SERVERs.
I guess the method I described allows identity theft on the client side.
I cant find a way to easily get id tokens from an authorization server to a client (which I could then use to authenticate to multiple authorization servers). My clients are trusted. I want to use native apps and implement open id connect among them anyway.
I do not want to use any websites as of now and still need to be able to have a secure communication with associations of claims to users and everything. Are OpenID Connect and its possible 'Flows' appropiate for this? Are there any other implementations that would allow the flow I described (or mabye derivations of OpenID Connect)?
It's not recommended but if you really don't want to use a browser (which is somewhat anti-OAuth/OIDC and is full of limitations) then ResourceOwnerPassword grant type is the one you'll need to use. This will not return an id_token though, just an access_token.
id_tokens exist to support front-channel browser-based sign in flows, they serve no purpose if using the ROP grant type.
Access tokens are issued by the authentication/secure token service (IDS4 in this case) and grant the client (optionally with user consent) access to the resource. The resource then has its own authorization rules to enforce scope and user-related ACL/business rule access controls.
I am looking to implement SSO in all my future php/angular applications. I see there are services (Auth0, oauth.io, etc) that are sort of the middle man of an SSO app and there are protocols such as OAuth 1.0/2.0 but in regards to creating a custom SSO solution (using aforementioned OAuth protocols, I assume), I am a little foggy on the complete flow of the process.
What I do get:
App gets Access Token
(optional) App validates Access Token
App (with Access Token) gets access to a particular API and returns result. For
example, Facebook profile information.
What I don't get:
What to do with that information once I have it. Do I retain the access token and request information from the API source each time they login? How do I relate my own application data to the API data? Would I create a different kind of user record that just contains the access token and application's userid?
Do I retain the access token and request information from the API source each time they login?
If the token does not expire, you can hold on to it in a data store and use it with each request. Many times, though, the token will expire, and you need to request a new one each time you start a session. In this case you'd probably store the token in memory instead of a permanent storage location.
How do I relate my own application data to the API data?
I think we'd need to know a little more about your application to answer this question.
Would I create a different kind of user record that just contains the access token and application's userid?
Again, we'd probably need a little more information about your application. If you were persisting the token (in the case that it doesn't expire), then you need to make some considerations about how you want to store it. If not, you can probably just put it into a local variable or session.