WSO2 API manager OAuth scope definition at Application Level - wso2

We just started evaluating WSO2 API Manager and found a potential feature missing in the product or may be with some tweak this may be achievable, so looking for some guidance on the below.
We define User Role and associate a User with that Role.
Create an API on API Publisher and define resource scopes mapping to Role
defined in above step
Generated Token specifying the scope defined in above Step and able to consume the API with access_token having the right scope
$APIM_ENDPOINT/oauth2/token?grant_type=password&username=VENDOR_USER1&password=VENDOR_PASS1&scope=scope_customer_creation scope_transaction_query scope_rates_query scope_product_query
Challenge
For large implementations where we have 3000+ APIs with different resources (GET/PUT/DELETE), defining of different scope for each of this APIs is not practical. And Secondly, when subscribing the APIs (currently 50+ subscribers), it would be impractical for them to specify so many scopes on the Auth Token generation Endpoint.
And the major issue here is if a new API is released with a new scope, API subscriber has to generate a new access_token including new scope which makes it impractical again as the token is cached on their end as per SLA default - 15 minutes. Reducing the token duration would require change on all the API subscriber end and also will increase the API calls for token fetch which doesn't make any sense.
Approach/Suggestion
Is there a way to define these scopes at Application level instead of per API resource? So that we can create a User & Role and associate that role to the application and not the individual APIs. In that way we can add as many APIs to Role or Scope and associate it with subscriber's application only.
So in total we only have to define 50 Roles/Scope and assign APIs to these scopes as per subscribers need. So the total permutation will be reduced, and any new addition of API will not require fetching of new token as the existing token will have only 1 fixed scope defined at application level and we can just add this API to the Role.

Related

No able to add custom scope in AWS Pre-Token Generation trigger

I have AWS Cognito user pool with one Allowed custom scopes for my app client i.e. admin-only. I have two kinds of users 1. Users in Admin Group 2. Non-Admins users. For my one of the AWS API Gateway Routes, I need to deny the access if user from non admin group is hitting the API Url, basically its allowed only for users which are part of Admin User group.
I can achieve it through adding an Authorization scope on API gateway route with this custom scope and then adding a scope manually when I request an Authorization token in Hosted UI popup. But in my app, I don't want to add this scope manually, rather want to add this scope when the token is generated. I explored Pre-Token Generation Trigger but not able to see the way to override or add scope attribute in it?
Question is, is there a way to add/override custom scope in pre-token generation trigger ? If yes then how ? But if there is no way, then how to solve my use case ?
You can use the claimsToAddOrOverride attribute in the response to replace the scopes value returned in the token with anything you want, BUT you cannot see the existing values in the lambda it seems so would need to know the full set of values up front

Expose limited method from specific API : WSO2 API Manager Version 2.6.0 free

I want to expose limited methods from my micoservice to outside.
I have 2 applications, each of one have its own access token (App1 and App2). Able to subscribe API with all methods to App1.
Want to subscribe same api with limited method's(not all methods) to App2.
Example : App1 ---subscribe ---X microservice (X having 2 post method's)
App2 ---subscribe ---X microservice should expose only one method from out of 2
You can achieve this using scopes.
Let's say you have an API with the following resources and respective scopes.
/check-status
/upload-photo
/upload-file
Then you can create 2 scopes as read and write. The read scope is attached to read role and write scope is attached to write role.
Apply the scopes to resources as follows.
/check-status : read
/upload-photo. : write
/upload-file. : write
In the devportal, when a user1(with read role) logs in, he can create an app and subscribe to the API. When generating an access token he will get only the read scope. He will see both the scopes. But the request is protected with the scope. So users with that scope only can access that particular resource.
Refer - https://wso2.com/library/articles/2017/01/article-an-overview-of-scope-management-with-wso2-api-manager/

Serverless AWS - is it worth using custom authorizers (as a lambda)?

Hey I am getting started with the serverless framework, apigateway, lambdas and authorizers.
Here my questions:
In order to verify a proper JWT token (which seems nowadays the best solution for serverless authentication), I would need a client id. Since the authorizer lambda is not capable(?) of reaching any other parameters of the request into the lambda except for the token itself, this is a difficult task to do. How can I achieve this?
Since with every authenticated call, an additional lambda is called, my costs are doubled?! May be I am misunderstanding something here, but it seems to me like implementing a method for verifying my token without using the authorizer is cheaper and I don't need to implement the authorizer lambda itself.
The whole point of OAuth2 is that at the point of authorization you don't care who the bearer presenting you with a token is or which client they are using (web app, Postman, etc.), only that the token is valid for whatever the token bearer is trying to do. You trust that the authentication has happened because the token issuer has done the authentication.
When you talk about the aud(audience) (from comments) in JWTs, which may or may not be included dependent on the JWT issuer, this is intended to reflect the service or services that the JWT is valid for.
This could for example have a value of 'myAPIName' or 'myAPIName/test' or even ['myAPIName/test1', 'myAPIName/test2'].
If you need to validate an individual aud claim you have two choices, you can either have different Lambdas authorizing different api routes and methods with hardcoded aud variables or you can get the name of the api being called and map it back to something that would match an aud claim.
For example the method arn for the incoming request can be found in event.methodArn. This looks like arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/ potentially with [{resource}/[{child-resources}]] dependent on your implementation. With a bit of string manipulation, you could map this back to the format of an audience claim (whatever that looks like for you).
If you would rather work an api name instead of an api name you can use the apigateway.getrestapi method for whatever sdk you are using. Documentation on this method for the JavaScript sdk can be found here.
The JWT may have a sub(subject claim), again dependent on implementation of the JWT issuer, this could relate to any of your users (or at least the users the JWT issuer knows about). Validating this beyond checking the signature of the JWT is pointless. The best you could do is check if that user exists and only if you have access to the same user database that the JWT issuer does. Although this can be used to ensure that UserA only has access to UserA's data. Again, you are trusting that the fact a bearer has a token is proof that they have authenticated (proved who they are).
I hope that answers part one of your question.
In regards to part 2, the advantage of using a Lambda Authorizer over doing the authorization in the target Lambda is caching.
So envisage I have a token valid for one hour and I call your API once every second for 30 minutes (1,800 calls). You have a Lambda authorizer with a response cache time of 10 minutes. That means you check the JWT 3 times for 1800 api calls.
But if you do the validation of that token in your target Lambda, you are doing that processing 1,800 times.
There is authentication with AWS Cognito which will allow you to use authentication outside your application and still being able to let your application divide the users into subgroups based on custom roles or similar.
If for some reason you cannot use AWS Cognito (Why not?) there is both the possibility of custom authentication (the same for each function with SLS) or even authenticating with custom code inside each lambda function.
I would recommend to use Cognito, and only custom if you know you need it.

Changes to the scope of an API endpoint are not taken into account unless restarting WSO2. Product bug? If not, any way to configure this behaviour?

Starting with an API defined in WSO2 with no scopes associated to its endpoints...
... I get an access token and invoke them correctly.
Now I modify and publish my API, assigning a scope to one on the endpoints so that it requires the editor scope:
Now I invoke that editor scoped endpoint with the previous access_token and it works. This shouldn't happen since the token was given with the default scope, not the editor one.
Now I restart WSO2 and try again with the same token, getting the expected result of access denied:
(900910) - The access token does not allow you to access the requested resource</ams:description></ams:fault>%
I have needed to restart the platform so that scope changes are considered!! Is this a bug, a expected behaviour (it shouldn't...) of is there any way to force the refreshment of the endpoint requirements (appart from just publishing the changed API).?
If you generate a new access token after either modifying or deleting
a scope of an API resource that you had previously invoked, you will
not be able to access that particular resource of the API for a period
of 15 minutes, which is the default Gateway cache period, because the
WSO2 API Manager Gateway is designed to cache the details of the
resource on its side.
Ref: https://docs.wso2.com/display/AM250/Scope+Management+with+OAuth+Scopes
This is not a practical problem in a typical production environment, as API updates in a production environment are very rare.
However, if this is really a problem for you, you can override the default scope validator[1] by extending it to not to use this cache. This is configured in identity.xml.
[1] https://github.com/wso2-extensions/identity-inbound-auth-oauth/blob/master/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/JDBCScopeValidator.java#L92

How to check for Cognito permissions in API Gateway

Trying to understand how to use Cognito and API Gateway to secure an API.
Here is what I understand so far from AWS documentation and the Cognito user interface:
Clients
www-public - public facing website
www-admin - administrators website
Resource Servers
Prices - for this simple example the API will provide secured access to this resource.
Scopes
prices.read
prices.write
Again, very simple permissions on the API. Public www users can read prices, administrators can write them.
API Gateway
GET /prices - accessible to authenticated users that can read prices.
POST /prices - only accessible to administrators
Users
Administrators - can update prices via the POST method.
Non-administrators - cannot update prices.
Based on this...
Each client will request the scopes it is interested in. So for the public www site it will request prices.read and for the administration site both prices.read and prices.write.
The API Gateway will use two Cognito Authorisers, one for each HTTP Verb. So the GET method must check the user can read prices and the POST method that they can write prices.
The bit I don't see is how to put all of this together. I can make the clients request scopes but how do they now connect to user permissions?
When the token is generated, where is the functionality that says "Ok, you requested these scopes, now I'm going to check if this user has this permission and give you the right token?"
I understand that scopes ultimately related to the claims that will be returned in the token.For example, requesting the profile scope means that the token will contain certain claims e.g. email, surname etc.
I think based on this that my permissions will ultimately end up being claims that are returned when specific scopes are asked for. The fact that the two clients differ in what they request means that the prices write claim an never be returned to the public www client. It would never issue a token if the prices.write claim was requested.
What I can't see is where this fits in Cognito. There is the option to put users into groups but that is pretty much it. Likewise, there is nothing (that I could see) to relate scopes to claims.
I'm coming from a .Net and Identity Server background. Certainly in the last version of Identity Server I looked at there was a handler method where you would work out which claims to put into a token. I guess this would map into one of the custom handler lambda functions in Cognito. From there this would need to query Cognito and work out what claims to issue?
The final piece of the puzzle is how the API Gateway checks the claims. Can this be done in API Gateway or does the token need to be inspected in the Lambda function I will write to handle the API Gateway request?
Certainly using Identity Server and .Net there was a client library you would use in the API to inspect the claims and redact permissions accordingly. Guessing there is something similar in a Node JS Lambda function?
A few assumptions there as I'm basically in the dark. I think the basics are there but not sure how to connect everything together.
Hoping someone has figured this out.