There are three communicating parties in our system:
Frontend
Service A
Service B
plus we have stand-alone security token service, our identity provider.
Authenticated user interacts with Frontend, it calls Service A, which in turn calls Service B. User's access token is passed through this pipeline using "poor's man identity delegation". Service A and Service B authorize (or not authorize) user's actions based on claims in passed identity. Everybody is happy!
But now I ran into situation when Service A has no user context during operation. It happens:
during startup
when Service A processes message from message bus
when timer fires
In each cases Service A needs to call Service B to obtain some data, but it receives 401, because no access token passed to Service B.
Are there any best practices how to handle such situation? The only idea I have in my head now is to register 'System' user (possible user per Service A, Service B, Service C etc.) in our identity provider, obtain access token for this user and use it in cases described above. But I smells bad for me and I'm looking for alternative ideas.
Any suggestions would be appreciated. Thank you!
Short answer would be: If you have no one to Act As then Act as yourself.
Even when using "poor's man identity delegation" Service A authenticates at STS using some sort of mechanism. In the link you posted a certificate is being used. So implement a new way of getting token. You already have a method which gets ActAs token so now you need to implement a method that will get user token (for Service A).
Your STS should already know this "system" user because it is allowing him to request ActAs tokens. You just need to assign some claims to the system user that will define what it can do even when it is not acting on behalf of a any user.
Related
I have a Django Rest API with JWT authentication which is the backend for a Angular frontend. There are many clients who use the service with our frontend. Now some enterprise clients wanted to integrate the APIs from their system's backend. I don't want to remove JWT from current APIs. I am planning to create new APIs in the same backend with OAuth token for those users.
I wonder what is the best way to implement OAuth for this scenario.
I am thinking Client Credentials grant type is the best way.
Question1: Am I right that client credentials is the right approach ?
For those enterprise users, it is sufficient they get just access token through the UI interface so that they can access all our APIs.
But here the problem is one additional step of getting the Client ID and Client Secret first and using that to get Access Token.
Question 2: What is the use of client ID and client secret ?
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
Question 4: If I am giving them Access Token without client id and secret, is that fine to have infinite expiry time? and
TLDR; How to implement OAuth when the resource server and auth servers are same ?
There are 4 grant types in oAuth2 which is meant for different scenarios.
client credential : the consumer (app) make calls to back-end using the bearer token created using apikey(or clientId) and secret only. Mostly used for anonymous calls where generic information is retrieved.
Resource owner password credential (ROPC) : the consumer (app) make calls using the bearer token created using apikey, secret, username and password. Mostly used when you(your authorization server) already know the users(user database is handled in your own system).
Authorization code : the consumer (app) make calls using the bearer token created using an authorization code. The authorization code is provided by a 3rd party (which actually has/manages the logged in user data) and the created authorization code linked to the logged in user. Google and Facebook log in for various sites is a typical example. Facebook/Google gives an authorization code for those websites and they exchange that code for a token.
Implicit grant : Mix of password credential and authorization code. Instead of authorization code, you get a bearer token from the 3rd party authorization server.
Question1: Am I right that client credentials is the right approach ?
I think you can use CC if there is no user level logics in your backend. If userlevel involved, may be ROPC is a better choice
Question 2: What is the use of client ID and client secret ?
Client ID and Client Secret is very similar to username and password in an application level, which is used to obtain bearer token.
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
If you are implementing oAuth2, your consumer should create the access token. But looking at your use case, may be even a simple hash of userId+timestamp is sufficient. ;)
Question1: Am I right that client credentials is the right approach ?
Yes. Providing the new APIs do not need to be called in the context of an end user.
Question 2: What is the use of client ID and client secret ?
The client ID allows the auth server to identify the application
requesting the token (it's often carried through to the access token
too, allowing the API to identify the calling application).
The client Secret means the auth server can trust that the client is
genuinely who he says he is as only he should have the private client
secret for his public client ID.
It's effectively a username and password in this scenario.
Question3: Should my backend hide the process of generating Client ID
and Client secret and just give Access token (or) give them Client ID
and Client Secret and ask then to generate access token ?
Your Auth server should issue the client credentials to the application once and the application should provide those credentials every time they wish to obtain a token via the client credentials grant type.
authorization code grant, or implicit grant might be more suitable for this scenario. The first one allows you to add an authentication step before the tokens are returned to the users (might be useful if you want to integrate your JWT authentication to this as well) and the second one is mainly used for single-page applications, and does not include an intermediate authentication step. This one would be useful if you want to improve efficiency.
client_id and client_secret are given to you when you register a client application in your identity provider(authorization server). This client application does not mean an application or an API belonging to your clients, but your own application to which you plan to incorporate OAuth(and OIDC). These two parameters are useful when making the requests to authorization in order to obtain tokens. The server uses those values to determine whether the request is made by a valid application. Only you have access to those values as you will be the one who's registering the application with the server.
I think this question is answered in the previous section.
I think it would be better if you go through this before doing any implementation. It provides most of the basic knowledge you should have before implementing an OAuth system. I hope this answer was useful to you.
What is the difference between these two approaches of initializing a new AmazonCognitoIdentityClient?
AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient(
new BasicAWSCredentials("access_key_id", "secret_access_key")
);
identityClient.GetOpenIdTokenForDeveloperIdentity()
-
AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient(
new CognitoAWSCredentials ("IDENTITY_POOL_ID", "REGION_NAME");
);
identityClient.GetOpenIdTokenForDeveloperIdentity()
Although most examples on the internet show BasicAWSCredentials being used to instantiate a CognitoIdentityClient, but the method signature in the doc says it accepts AWSCredentials class - both BasicAWSCredentials as well as CognitoAWSCredentials are subclasses of the AWSCredentials class. Hence, i am assuming both should be working normally i guess???
I am trying to understand how will this difference, impact the following:
privileges,
timeouts,
etc?
API reference for cognitoIdentityClient constructors is here: http://docs.aws.amazon.com/sdkfornet/v3/apidocs/index.html?page=CognitoIdentity/TCognitoIdentityCognitoIdentityClient.html&tocid=Amazon_CognitoIdentity_AmazonCognitoIdentityClient
In client device you should instantiate AmazonCognitoIdentityClient client using CognitoAWSCredentials. Using STS service, AWS client will obtain temporary credentials that will let the client assume the role you previously defined in your identity pool. Typically this role would have very limited access to your AWS resources. (S3 upload to a specific bucket etc.) This is like giving out to people a special type of your car key which can only turn on the music system, not the engine.
On the other hand GetOpenIdTokenForDeveloperIdentity is a special API call that needs developer credentials. You should never deploy developer credentials to any client device and you should keep it only on your server. Once you instantiate a AmazonCognitoIdentityClient using developer credentials on your server, you can expose a REST endpoint for clients to obtain OpenId token (for a given identity id or creating a new one). Let's assume that your users are logging in to your API using their username and password and you return them a custom access token which is stored in your database. After that your endpoint may implement this logic:
Fetch unique identifier for your user using custom token (user id, username, e-mail etc.)
Use LookupDeveloperIdentity and find out the identityId for the given username.
Use GetOpenIdTokenForDeveloperIdentity with found identityId and send back to the client. So they can "login" to that identityId.
If this user has not any identityId assigned to its username, create a new one and send back.
As you see developer AWS tokens are enabling a couple of sensitive API calls. Now let us assume that client had developer access token and thus has access to GetOpenIdTokenForDeveloperIdentity call. Then they would be able to generate OpenId tokens, switch to other people's identities easily and access their private data.
If you don't use developer authenticated identities (https://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html) you do not need GetOpenIdTokenForDeveloperIdentity mechanism though. If you are using only public authentication methods (Twitter, Facebook etc.) you should ignore the second paragraph and use CognitoAWSCredentials.
As described in Çağatay's answer, the BasicAwsCredentials are instantiated with your developer credentials. What he described about when to use each constructor is absolutely correct in every case other than developer authenticated identities.
Since this code will be deployed on a back end service, it's exposure is less of a concern. Mobile clients will communicate with this server and get the token from it, with which they will get credentials. The credentials are never exposed to the user in this pattern.
As you can see in the Cognito documentation, the sample has BasicAwsCredentials. An end to end sample is visible in this blog post.
I am about designing WCF service and security part looks toughest bit. The service will have two end points: SOAP and REST and will use form authentication. After reading a lot about security I decided to create separate Token Based Security Service (TBSS) which will be behind the my original service and there will be ws-trust between TBSS and my service. When client call my service to authenticate, authentication request will be passed to TBSS and TBSS will authenticate(or not) user and will return token which will be expired after a while. On subsequent client call, original service will take token and pass the token to TBSS with Method name and TBSS will authorize user.
What are the benefits of this model in my opinion:
User will not be authenticated each subsequent call which is very expensive.
My original service will stay stateless and
seamlessly scalable.
Security will be completely segregated from actual service.
Although everything looks ok for me I am still not feeling very confident as I haven't implemented this model before, so I don't know what kind of problems I will encounter even will I be able to complete this? I would be appreciated if you can share your opinion/experience/expertise.
I have an internal-facing RESTful web service. There are various client applications using the service, and the client apps themselves have end users. The web service needs to authorize requests based on the end user identities.
The question: What are the typical options for authenticating the end user here? That is, I want to authenticate the user, not the client application. (I don't mind if authenticating the client application is part of the scheme, but ultimately I need to know that the end user is who I think he or she is.)
One possible scheme, for example, would be to have per-client system accounts, and then have the client simply assert the user's identity (e.g. in an HTTP request header, say). So we authenticate the client application and delegate user authentication to the client. I don't think this is a very strong scheme, though, because it depends too much on keeping the system account credentials secret. I have seen too many examples of people e-mailing system account credentials around to put much faith in this sort of approach.
Another approach might be to have the client app, upon user login, use the user's credentials to get a token from the API, and then use that token for subsequent API requests. That way the authentication is user-specific without requiring the client app to hang onto the username/password credentials.
Anyway I'd like to have a better sense for the range of options I should be considering here.
The problem that you describe with "delegated authentication" is a real one. It means that a "client application" using it's credentials has access to the whole breadth of user data. This access can be used maliciously (for example a "semi-trusted" app harvesting api data) or negligently (for example an app accidentally exposing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)
Probably the most prevalent "token based" scheme is OAuth2 (http://oauth.net/2/), and the precursor, OAuth, which many sites choose to continue to use.
OAuth2 has a number of roles:
resource owner (the user in your case)
resource server (your api)
client (the apps you talk about)
authorization server (not clear who or what would fulfil this role in your case)
The basic scheme is that the resource owner authenticates using their credentials directly with the authorization server. They are then asked if they want to grant some information (which may just be a persistent identifier, or a description of the information exposed by your api) to some client. When they accept an 'auth code' is sent to the client and they use that (combined with their own credentials) to receive an 'access token'. This access token can then be used to authenticate against the resource server (which can check it's authenticity back against the authorization server).
Normally the way this is used is that the authorization server and the resource server are owned and managed by the same entity (for example google and facebook would fulfil this role) and then clients are independently managed.
The scheme can also be used internally within an organisation without the "explicit grant" which can still at least confirm that a specific end-user is present before releasing any data from an api.
I'm exploring basic service oriented architecture and I'm wondering how to best handle user authentication throughout the services.
As a very simple example, suppose we have a blog app that calls out to two other services:
A user/auth service for storing user data and exchanging credentials for an access token
A posts service for managing post data
Let's say a user of the application is attempting to delete a particular post and that only users with an "admin" role are allowed to do so.
The following requests would need to be made:
app -> auth
Authenticate the current user (via some sort of token). If the token is expired the app could redirect the user to a login form, etc.
app -> posts
Delete the post.
posts -> auth
Before a post is deleted, the post service needs to make sure the requesting user has permission to do so. Authenticate the current user (via token) and make sure they have the "admin" role.
This is an overly simple example but I'm curious how folks are dealing with auth throughout their services. It seems likely that each service would need to make a separate call to the authentication service in order to authorize the request. Is this the case? Are there better ways to handle auth in this kind of SOA?
Thanks!
You can implement an identity provider - Once a user authenticates with the authorization/authentication service she should get a token that identifies her. This token can identify her (roles/claims) and signed by the authentication/authorization service private key. When a service gets a security token and it is signed by a trusted authority it doesn't need to go to the authentication/authorization service again.
If your system has a higher security requirements (e.g. at the user level) you may need either elaborate claims or to access the authorization system on each request. I worked once on a system where certain types of info required authorization on every access and other types were ok with role based security - your millage may vary.