I am designing a REST API for multi-tenant app. I want to protect the API. The multi-tenant app can be subscribed by a tenant who in turn can have multiple users using the app.
I plan to use OAuth for the same. One of the possibility is to use OAuth's Client Credential Flow - where a client Id and secret is given to each tenant who subscribes to the service.
The problem with this approach is, I cannot differentiate between different users of the tenant as everyone uses the same client Id and secret to get access token.
The other option is to use the OAuth's Authorization token flow. But in this case, I am not sure how should be the interaction as it is API (non-UI).
Further, How this kind of use case be solved with SAML?
It can't. The SAML spec. doesn't have a way to pass SAML tokens to API's.
If you need user context, you need to use the authorisation grant flow. Once authenticated, you ask for a JWT tailored for that API (scope etc.) and then send that JWT to the API.
Related
I'm developing a set of microservices exposed as REST through WSO2 API manager.
Now, I'd like to call these services in Angular front end. What is the best way to handle user authentication and authorization?
I found it can be done through OAuth2 Password Grant as described here?
When user logs in, user credentials will be sent to specific WSO2 APIM endpoint (/token), it validates, generates the token and this token will be sent in header for subsequent calls.
Is this the best approach to this case?
Thanks in advance,
As mentioned in your question, https://apim.docs.wso2.com/en/next/learn/api-security/oauth2/grant-types/password-grant/
This method will only work when you have the resource owner's username and password.
Take an example, suppose you have published the APIs and created a user (resource owner) in the WSO2 store. this user is subscribed to the API using the application. the application will have a client id and secret, which will be used to generate the OAuth2.0 token. this token will be used to invoke the APIs.
Now in your angular project, one way is to hardcode the base64(clientid:clientsecret) and call the token API to generate the OAuth2.0 bearer token. use the generated token to call the APIs onboarded on WSO2. To protect your APIs from the attack, use rate limiting based on IP
Now take another situation, if you want the user to authenticate first, then generate the JWT token for that user using the password grant type (using actual user's username and password), and using that JWT generate the OAuth2.0 Bearer token which will be used to call the APIs.
Steps to be performed for the second situation:
during registration (from Angular), internally onboard the user in the WSO2 Identity Server. (There is a WSO2 API for the same)
After registration, generate the JWT token from the identity server by authenticating username and password. (Again for this, WSO2 API is there)
now using this JWT token, Generate the OAuth2.0 token from WSO2 APIM
use this token to call the APIs
The second approach is the ideal approach for user to service authentication and authorization using WSO2 as the gateway while the first approach mainly focuses on service to service authentication and authorization
Hope this answers your question
Reference Link: https://medium.com/wso2-learning/how-to-protect-your-apis-with-self-contained-access-token-jwt-using-wso2-api-manager-and-wso2-75673d8a4686
I'm struggling theese days on the possible way to configure an Authentication + authorization system to consume a REST API from a mobile application.
Scenario:
We've developed 3 independent portals for a big customer that serves several users.
To enable a SSO for the 3 portals we've implemented a SAML authentication system using SimpleSAMLphp.
Every portal has a service provider and they make assertion requests against a central IdP.
The IdP checks username and password against a database where passwords are hashed and stored during registration.
After the login, the authorization on the portals is handled by the session on the server, and so far everything was fine.
Now the customer asked us to develop a mobile application that will require the users to login and access several of their protected resources collected during the usage of the 3 portals.
We've decided to develop a frontend application using ionic that will consume a REST API made in node.js that will serve all the data (both protected and unprotected resources).
Now here comes the question: to authorize access to protected resources on the Api we'd like to use JWT to easily achieve a stateless system.
The doubt is how to perform the authentication? We've the opportunity to check the credentials directly against the database skipping the SAML process, otherwise we've to implement a solution where the SSO IdP acts as authentication provider and then when an attempt is successful the API app will get the response from the idp and then issue a signed jwt to the consumer client. Is this second way a common implementation? Is it possible?
What path do you suggest to follow? The first could be very easy to achieve, but since we're using html+js for the app's frontend, if we decide to use the second solution probably in the near future we could recycle some code from the app to modernize some functions on the web portals, maintaining the jwt pattern and consuming the new Api also on the web.
I believe that in this case will be easier to ask a token to the new api using someway the logged in user's data already in the session of the portal. Sounds possible?
I hope that everything was clear, any help will be appreciated!
Thanks
The key goal here is to code your apps in the best way, via
the latest security standards (OAuth 2.0 and Open Id Connect).
SAML is an outdated protocol that is not web / mobile / API friendly, and does not fit with modern coding models.
Sounds like you want to do OAuth but you do not have an OAuth Authorization Server, which is a key part of the solution. If you could migrate to one you would have the best future options for your apps.
OPTION 1
Use the most standard and simple option - but users have to login with a new login screen + credentials:
Mobile or Web UI uses Authorization Flow (PKCE) and redirects to an Authorization Server to sign the user in
Mobile or Web UI receives an access token after login that can be sent to the API
Access token format is most commonly a JWT that the API can validate and identify the user from
The API is not involved in the login or token issuing processes
OPTION 2
Extend option 1 to federate to your SAML Identity Provider - enables users to login in the existing way:
The Authorization Server is configured to trust your SAML based identity provider and to redirect to it during logins
The SAML idp presents a login screen and then posts a SAML token to the Authorization Server
The Authorization Server issues OAuth based tokens based on the SAML token details
OPTION 3
Use a bridging solution (not really recommended but sometimes worth considering if you have no proper authorization server - at least it gets your apps using OAuth tokens):
Mobile or Web UI uses Resource Owner Password Grant and sends credentials to a new OAuth endpoint that you develop
OAuth endpoint provides a /oauth/token endpoint to receive the request
OAuth endpoint checks the credentials against the database - or translates to a SAML request that is forwarded to the IDP
OAuth endpoint does its own issuing of JWT access tokens via a third party library (if credentials are valid)
Web or Mobile UI sends JWT access token to API
API validates received JWT access token
Im a bit confused about oauth2 and OIDC.
So supposedly with OIDC we now get the id_token which uniquely identifies the user in the same oauth2 flow.
But my understanding is - oauth 2 came out earlier than OIDC and OIDC support is not universal even at this point.
So how do current APIs that use oauth2 (without OIDC) work?
Let's say there is a mobile app that needs to use some API.
Is the idea that after mobile app get's oauth2 access token -> they always have to hit some endpoint like /me using that access token which will then provide user id information? and thus the api has to track which access tokens have been given to each particular user?
Sry this question comes out like request for some trivia info - but Im really new to oauth2 & OIDC and just trying to understand and make sure im not missing anything....
OAuth 2.0 NOT an Authentication protocol.
OAuth 2.0 is more of a delegation protocol where the Resource Owner delegates certain permissions to a OAuth Client.
OIDC is an Authentication protocol built on top of OAuth 2.0.
OAuth 2.0 should be used where a user (Resource Owner) is delegating permissions to an Application (OAuth Client) to perform some action.
OIDC should be used where an an Application (OAuth Client) needs to some "Level of Assurance" that the user (Resource Owner) is who he says he is.
The Authentication is done by a Third-Party (Authorization Server). The id_token allows the Client to access information about the user that the Authorization Server knows about (and hopefully has performed some verification).
As jwilleke answered it, OAuth 2.0 is for authorization. OpenID Connect (OIDC) is built on OAuth 2.0 adds Authentication layer.
Basically, OAuth 2.0 delegate the client application to access a protected endpoint on-behalf of the resource owner. In simple words, end user authorise the application access a resource/service. In this process, application does not receive any detail about the end user so it cannot authenticate/detect(In OIDC, application receive the id token, which is self-sufficient enough to authenticate the end-user) end user.
Q : Is the idea that after mobile app get's oauth2 access token -> they always have to hit some endpoint like /me using that access token which will then provide user id information? and thus the api has to track which access tokens have been given to each particular user?
From OAuth 2.0 perspective, there is no end user information sharing. But the token issuing identity provider understand the tokens it issued. Internally it can map end user details, permissions and anything it requires to process it. With that, when the API (resource server) receive the access token, it can validate the token. Note that resource server and authorization could be the same or different. And these are implementation specific details. Alternatively one could use token introspection as defined in rfc7662 to detect validity of issues access tokens.
Example scenario
You have mobile app A. And it have the ability to use a service B (protected by Access tokens) which is exposed by service provider G. Assume there is a user Alex who have already registered at SP G so have access to service B and uses app A. And SP G have OAuth 2.0 implemented so service B accepts access tokens issued by SP G.
User Alex use App A and there is a functionality in the App A which need to consume service B. App A require authorisation from Alex to consume service B on-behalf of him/her. In doing so, there will be a user login process and at the end SP G issue access token to App A. Does it convey identity of Alex ? No it does not. But App A can now consume service B using access token it received. Service B fully understand and can validate access tokens issues by SP G. IMO This is OAuth 2.0 in nutshell.
p.s - Substitute known services like Google calendar, Google identity and your android app so that it make more sense.
I have implemented an OAuth2 register workflow (in Java) according to rfc6749
I'm using GitLab as OAuth2 Provider.
After the user granted access to my application for his account, I get an OAuth Token (along with refresh token and other stuff), I am able to make API requests on behalf of the user, so this is working fine.
This way I can get the users e-mail adress which I use to create an internal user.
My questions are:
Is it practice to issue a token that is generated by my application for the user (along with the OAuthToken) or should I just use the token that has been issued by the OAauth Provider? (My App also has local auth with bearer tokens). This token will be used for further API - CLIENT communication (stored in Angular2 local storage as bearer)
How to do login only? When a OAuth User accesses my web service, how do I know that this user is a OAuth User and which OAuth Token belongs to him? How can the user login without providing e-mail or password? (The user has no password) I guess I have to redirect him to the OAuth Provider again, but I don't want my user to grant access everytime he logs in.
Answer 1:
Though you can use the token provided by OAuth provider, you SHOULD NOT use it considering the risk that may arise exposing it to the public.
Instead you should securely save the token provided by OAuth provider into the database and use another token for authentication of further api calls. (you could use JWT)
Answer 2:
There are two types of systems
Which always uses OAuth provider for identifying user. (Ex. Tinder)
Which provides both OAuth Login and Traditional login/signup. (Ex. Quora, Instagram)
If you want your application to follow 2nd approach, you should ask the user to create password for the first time when the user logs in using OAuth provider.
This will allow the user to log into your application by both methods, traditional as well as OAuth
To identify users of your application, you should either use HTTP session or issue your own tokens. Do not use tokens generated by the OAuth2 provider - they are meant to be used just by your backend (in role of an OAuth2 client).
To use an external authentication in your application, you probably want to use OpenID Connect, not a bare OAuth2. OpenID Connect extends OAuth2 and it's meant for authentication instead of the rights delegation. Then you use an implicit flow (instead of authentication code grant) with scope=openid, your frontend app (HTML+JavaScript) gets an ID token signed by the OAuth2 provider. After successful signature verification, your backend can trust that the client is the one described in the ID token (in its "sub" field). Then you can either keep using the ID token or generate your own token.
If I have an API secured with Azure Active Directory, what is the flow when an external API wants to talk to my internal API?
Is this just an API to API call as normal or is this a special circumstance and needs handling a different way?
Is this just an API to API call as normal or is this a special circumstance and needs handling a different way?
The special circumstance may depend on the confidentiality of the resources served by these api(s) and the level of security your application needs. In the end it is an api to api call only.
There are two approaches you can use if Azure Active Directory (AAD) is your Identity Provider for the entire application.
Application Identity with OAuth 2.0 client credentials grant provided by AAD. The calling API makes a request to AAD token endpoint with its client id, client secret (credential) and the application id (the unique id for the callee API) to receive an access token as response. This token is used as Bearer token to call the downstream API. In this approach client id, client secret, application id that are exchanged for an access token, are static values. Some one who has access to these values may find a way to compromise application security (highly unlikely).
The second approach is Delegated User Identity with OAuth 2.0. A request is made to AAD token endpoint with client id, client secret, the access token received as part of calling the tier1 API and a special on_behalf_of parameter to receive an access token, refresh token as response. We preferred this approach as it uses a dynamic value (access token from tier1 api) and also provides a refresh token.
You can read more about these approaches here
If you do not want to use AAD, you can use asp.net built in OwinAuthenticationMiddleware to generate and validate your own access tokens. As said earlier it all depends on your application requirements and implementation details, but in the end it is an API to API call.
Hopefully this is helpful, please let me know if you have any questions.
Thank you,
Soma.
oAuth is done for loggin user to a webservice (see also reference here).
Use OAuth to give your users access to their data while protecting their account credentials.
As another webservice wants to consume one of your service best way to do so is to have another authentication method in order to authorize
Other API, I assume you are talking of machines and not users (alias humans).
So best way is to provide another auth mechanism in order to authorize machines to connect to your API in a safe way.
A simple way to do a machine connection is using a private PKI with public/private key.
A good reference for PKI : http://docs.oracle.com/javase/6/docs/technotes/guides/security/certpath/CertPathProgGuide.html