How to setup WSO2 APIM with WSO2 IS and an identity provider? - authentication

My question is rather large as I didn't know exactly what to ask, if you have a more specific title don't hesitate to edit.
I'm currently working on a poc where the scenario is the following :
the end user (bob) wants to access some application (randomApp)
randomApp calls our apim which will first check that the randomApp is registered onto the store with an access token and has access to the API
then pass it to the identity server (IS) which will check with the inbound authentication component with for example openID Connect that the randomApp is registered as a service provider and that OAuth key & secret match
this randomApp has some federated authentication declared in the local & outbound auth component to redirect it to an openID Connect (OIC) server where bob will actually authenticate to access the ressource
the OIC server is declared as an identity provider with some credentials from the OIC server, all the URL from the OIC server are declared auth, token and callback endpoint.
bob authenticate correctly, the info is then passed back to the IS which give it to the SP who can finally call the API and display bob's information.
Is this scenario conceivable ? I'm having a hard time grasping every single interaction between all the components. Let me know if some steps are not necessary, overkill or else. I've been playing around with the playground from wso2 but I'm not sure that it depicts exactly the scenario I want.
To summarize : end user -> service provider -> wso2 identity server -> OIC server and go back the other way. What would be the best "setup" for this ?

I hope the article use-cases-of-utilizing-saml-with-wso2-api-manager will be useful for your requirement. In this article, the flows are explained with SAML protocol. You can use the same functionality with OIDC as well.

Related

Chaining OpenID tokens

I'm working in microservices environment, where each service authenticates using OpenID Connect to an authentication service (local IdP), based on Users I keep locally on my Database.
Now, I want these services to be able to authenticate using Azure, Google, etc.
Can (and should) I modify my authentication service to allow redirection to another IdP, and replace or chain the token to my proprietary token for my services?
Is there a simpler way?
How can I allow users to login both using name / password OR external IdP?
I'm doing some research on the topic by myself as well and from what I've found until now, it seems that there is a urn:ietf:params:oauth:grant-type:token-exchange grant type that should allow exchanging external idp token to an internal one as described in some spec.
It should be supported as part of the openid connect /token endpoint so as long as the local idp supports it, I guess that this should be the best practice to achieve what you are looking for.
I'm currently looking into mitreid-connect idp implementation as local idp and some of my requirements is to also allow SSO with third parties while being able to issue a local token from the external user identity.
Will update as it goes...
If you manage all the SP (your microservices) it's definitely easier to implement it on your common IDP.
But if the SP are external ones (like existing services you just installed) and they already implements the public IDP you want to use, it was be a bit harder to pass through your current IDP without problem.
I'm guessing you are in the first case (you made all your SP) so I will elaborate it:
When your current IDP will authenticate user on others public IDP, it will get some information (email, name, etc.) and you can normalize those in your answer, to be sure your SP are completely agnostic of which original IDP was used. It will be better for you if the future to debug this setup. And of course to add a new public IDP...
But if you need to use some specific call to original IDP, (let says Youtube API for example) you could have a agnostic API on your common IDP which will forward to the appropriate proprietary API of original IDP, or deny the request if the IDP does not have a video system.
Or you could give original token to your SP, in a custom field or scope of your oidc token, so for example an SP dedicated to video could directly call Youtube API with the google user token.
I recently did a similar setup for my company. I would like to share the overall structure to give an idea about our solution. Hope it helps:
Our authentication server is an node express server with following properties:
Hosts static login screens to allow authentication against local database via email + password, as well as provides links to authenticate with external OAuth2 providers.
Both local and external authentication requests are forwarded to Passport.js Authentication strategies
After successful login, both local and external Passport.js strategies respond to a callback. Upon this response, a session object is created via express-session and a cookie is sent.
At this point, cookies can be used to exchange JWT's, so that authentication against stateless API's can be possible with Bearer Access Tokens.

Do users of a third party app accessing our API's have to log in with us even if they've already authenticated with their their system?

We have a third party company developing a mobile app and they want to call our API's. Our API is protected with Identity Server 4 which uses OpenID Connect and OAuth2. In order to access our API's would their app have to pop open a mobile browser so the user can log into our system? What if users already authenticated with the third party's identity provider? Seems like that would create a negative user experience to authenticate two different times while using the app.
My understanding is we would add their app as a client in Identity Server using the authorization code grant. Would we add their identity provider as an identity provider that our Identity Server can call?
Any help on this would be greatly appreciated. I've researched myself into a hole.
would their app have to pop open a mobile browser so the user can log into our system?
You are pretty much right on your assumptions that their app would have to somehow initiate oidc flow to allow the users of the mobile app to authenticate with the authority of your API (identity provider).
Seems like that would create a negative user experience to authenticate two different times while using the app.
It seems that this is what's holding you back. Firstly, that mobile app's identity provider is separate from your API's authority and it is important to understand that the "user" authenticated with the other identity provider means close to nothing to your API because the token has been issued by a different authority and it's not even a "user" from your user base.
My understanding is we would add their app as a client in Identity Server using the authorization code grant.
Yes, but check also Authorization Code grant with PKCE which adds extra security measures.
Would we add their identity provider as an identity provider that our Identity Server can call?
Yes, you will need to do that, but this is just a start of the things you would need to do to achieve what you are looking for. Because you already have Identity Server 4 in place, I assume your systems already have an established user base, therefore if you just redirect to the external identity provider, once a user authenticates there and the token is issued back - that kinda means nothing because you don't have any kind of mapping from the user of the third party system to the user of your system.
There is pretty much nothing out of the box in Identity Server 4 that will help you with this, but one way to tackle this is to implement some sort of account linking mechanism, where the users would first have to "link" their account in your system with the account in the third party system. With account linked, you would have means to issue claims related to your system.
Identity Server 4 absolutly has out of the box solutions for this. If they didn't, what would be the point calling themselve a OAuth 2.0 framework?
You do not need to initiated a oidc flow like stated. What does that even mean anyway? oidc is connection protocol, not a flow. Flows include hybrid, implicit, clientcredential, etc.
You could obtain an access token for your 3rd party app a number of ways all use the token endpoint built into identity server 4 specifically for creating access tokens The most common is using the ClientCredential flow, where you gain a bearer token by hitting the identity server 4 token endpoint passing the client_credentials grant type with the ClientId of the client they want to access, a shared secret supplied by you, and the api scope they are attempting to access.
Another option is you could create a user for this client on Identity Server 4, then gain an access token using the ResourceOwnerPassword flow by hitting the token endpoint passing the password grant type, clientId, username, and password, again along with the api scope they want to access.
For information on how to do all of the above check out his link. It will help you on your way.
http://docs.identityserver.io/en/latest/endpoints/token.html

Custom Authentication Service in Kong API Gateway

We are currently analyzing the API gateway for our microservices and Kong is one of the possible candidate. We discovered that Kong support several plugins for authentication but the all based on users stored in Kong database itself. We need to delegate this responsibility to our custom auth HTTP service and don't want to add these users in API gateway database.
It's possible to do this with some code around, instead of using the OpenID connect plugin; in effect you need to implement an Authorization Server which talks to Kong via the Admin (8001) port and authorizes the use of an API with externally given User Ids.
In short, it goes as follows (here for the Authorization Code grant):
Instead of asking Kong directly for tokens, hit the Authorization Server with a request to get a token for a specific API (either hard coded or parameterized, depending on what you need), and include the client ID of the application which needs access in the call (you implement the /authorize end point in fact)
The Authorization Server now needs to authenticate with whatever IdP you need, so that you have the authenticated user inside your Authorization Server
Now get the provision code for your API via the Kong Admin API, and hit the /oauth2/authorize end point of your Kong Gateway (port 8443), including the provision key; note that you may need to look up the client secret for the application client id also via the Admin API to make this work
Include client id, client secret, authenticated user id (from your custom IdP) and optinally scope in the POST to /oauth2/authorize; these values will be added to backend calls to your API using the access token the application can now claim using the authorization code
Kong will give you an Authorization Code back, which you pass back to the application via an 302 redirect (you will need to read the OAuth2 spec for this)
The application uses its client and secret, with the authorization code, to get the access token (and refresh token) from Kong's port 8443, URL /oauth2/token.
It sounds more involved than it is in the end. I did this for wicked.haufe.io, which is based on Kong and node.js, and adds an open source developer portal to Kong. There's a lot of code in the following two projects which show what can be done to integrate with any IdP:
https://github.com/apim-haufe-io/wicked.portal-kong-adapter
https://github.com/Haufe-Lexware/wicked.auth-passport
https://github.com/Haufe-Lexware/wicked.auth-saml
We're currently investigating to see whether we can also add a default authorization server to wicked, but right now you'd have to roll/fork your own.
Maybe this helps, Martin
Check out Kong's OpenID Connect plugin getkong.org/plugins/openid-connect-rp - it connects to external identity and auth systems.

How does Azure Active Directory authentication for Azure API Apps work?

I'm trying to call an Azure API App configured with Azure AD authentication. Assume for the purposes of this question I cannot use the Azure SDK and need to write code to get a token and insert it into the API request.*
I have established that there are two modes - 'client flow' and 'server flow', where client flow entails following at least one redirect to an issuer to get a token, and server flow where the server does this for you. Since I'm talking about doing this in code, following redirects would be possible but fiddly, so I'd prefer to use a mode where the URI or URIs to visit are known ahead of time and return content, rather than redirecting. The following diagram illustrates how the gateway routes all requests.
I think the mode I need is client flow, which would go something like:
Get an access token from the identity provider (which is what? how do I find out where this resides? what is the format of the request I have to send to the IdP?)
Pass the access token to the gateway (in what format?)
Receive another token in the gateway response
Supply this token in a header when making an API request (which header?)
How am I supposed to do this? The Azure documentation doesn't give enough detail about how it works, and expects all users to just use the SDK, which hides what is actually happening.
The actual reason is that ultimately this will need to be called from BizTalk, which uses the WCF WebHttpBinding to call restful services. I'm writing a custom behaviour to insert a token header into the request, but I need to know how this token should be acquired. It's possible to run arbitrary code in BizTalk but trying to do this makes the solution complicated, and config-only or mostly-config with minimal, loosely-coupled code is the simpler solution
Just want to understand your scenario better, Because you are going to use it from BizTalk Receive Pipeline, The scenario can be simplified by enabling a customer authentication token right ? Basic username and password for your API you have hosted on the cloud. Does BizTalk want to authenticate it self with tokens for each AD User ?
To answer some of your questions
Get an access token from the identity provider (which is what? how do I find out where this resides? what is the format of the request I have to send to the IdP?)
After you have configured your AD configuration, Once you have completed the authentication, I am assuming your are using ASP.Net here, You can find everything you need about the claims on your Thread.CurrentPrincipal, You can convert it to ClaimsPrincipal like so var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal; and then you will find a lot of good information on this object. Name of the user logged in, list of claims the principal has etc. I have not explored every avenue here, but this should be a good starting point.
Your API App is running on this process which means you have access to these claims in your API App code as well.
I would build a custom pipeline in BizTalk that uses Azure SDK to authenciate and build this scenario, it is a bit complicated but it will give you more control over what goes through the pipeline as well when authentication fails with permission issues and so on.

oAuth2 - WSO2 API Manager and Identity Server Integration

I would like to implement an architecture based on oAuth2 in which the token is generated by the WSO2 identity server (Auth Server) and the API manager is used as the Gateway (resource server).
I understood it's necessary to change the Identity_Server/repository/conf/carbon.xml and set the value false for the element <HideAdminServiceWSDLs>false</HideAdminServiceWSDLs> in order to enable the admin Service of token validation exposed by the Identity Server. Also I think it's necessary to configure the APIManager.xml to configure the API manager to check the token validation using a service exposed by the identity server.
But unfortunately the specific documentation is not available at https://docs.wso2.org/display/AM140/Configuring+api-manager.xm. Can someone help me understand how to achieve my goal ?
If it's correct to assume what you want is to, secure a exposed rest API with OAuth, using WSO2 IS, then the following link [1] will help you.
But since you are using WSO2 API manager, if there is no other restriction you can simply achieve this token generation functionality from API-manager itself. There is an OathTokenEndPoint exposed by API-M. You can call this endpoint with client-key and secret to get a token.[2]
[1] - http://movingaheadblog.blogspot.com/2014/02/securing-your-web-service-with-oauth2.html
[2] - https://docs.wso2.org/display/IS410/OAuth+2.0+Grant+Types+with+WSO2+API+Manager+Authorization+Code