I have a single node setup of WSO2 API manager and WSO2 Identity Server as Key Manager.
I have created a service provider(SP1) from which I'm generating a JWT token using client-credential grant type. I'm also adding some claims(lets say country) in the JWT token using openid scope and configuring the claims in service provider.
Now I created another service provider(SP2) from which I want to generate my access token using JWT Grant type and the JWT token generated above(from SP1) as JWT assertion value.
Command I'm using to create access token from SP2 using jwt grant:
curl -i -X POST -u <client-id>:<client-secret> -k -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<JWT-Token>' -H 'Content-Type: application/x-www-form-urlencoded' https://localhost:8243/token?scope=openid
My question have two parts:
Q - 1.) If I want to add any new claim(lets say email) at the time of using JWT grant i.e. when generating access token from SP2, how to do this?
I have tried adding extra claim configuration in SP2, it doesn't add the claims to access token except the claims that already existed in JWT token. Even if I'm not adding any claim in SP1, still it does not add new claim into access token.
Q - 2.) Lets say I have three users in my user store with given attributes:
Users
Name Country email
A India a#india.com
B UK b#uk.com
C US c#us.com
I have a service provider created by admin which is used to generte JWT token.
Now I want to add claims to this JWT token for any of these users without using password grant type. Is it possible to add user specific claims to JWT without using password grant. If Yes then how? If No then what could be the alternative I can use?
Related
I'm trying to give security to my APIs using WSO2 API Manager. I could achieved the configuration of WSO2 Identity Server to use an LDAP server with some users and made WSO2 API Manager to use this Identity Server as Key Manager. My questions are:
How can I configure end user to access an API? Is it needed to associate all the users to an application role in API Manager carbon?
The end users need to have two access token to access an API? One to authenticate in IS using (OAuth Client Key/OAuth Client Secret) and other to generate the access token to the API in API Manager using (Consumer Client Id/Consumer Client Secret)?
Is there any tutorial explaining all this steps and how to protect an API just for some users?
Basically, the token generation flow is different from grant type to grant type. For example, the jwt-bearer grant type that you are using to generate an access token has several steps such as,
Service provider requests the JWT from the IDP
Generating an access token from API Manager exchanging the JWT assertion.
This is because the usage of each grant type is different and using grant types depends on your security requirement.
The JWT Bearer grant is usually used in client apps, where user logs in providing user name and password and the rest are done in the application itself without any interaction with the end-user.
If you need to generate the token as the end-user, you can use the password grant type.
These are the steps that I made to configure WSO2 Identity Server and WSO2 Api Manager:
I've created a Service Provider in Identity Server and configured an OAuth/OpenId Connect. This generated an OAuth Client Key and OAuth Client Secret.
I've created an Identity Provider in API Manager, import a Public Certificate to authenticate the response from identity provider and use the OAuth Client Key as Alias to be checked by WSO2 API Manager when verifying the JWT Token.
I've created an API in WSO2 API Publisher, associated this API to an Interna/subscriber role and my end users to this role.
I've created an Application in WSO2 API Store to consume my Rest Service and subscribed my API to this Application.
I followed this article to these steps:
how-to-protect-your-apis-with-self-contained-acces
The problem are the steps to consume the Rest Service.
Request in WSO2 Identity Server to generate an access token to API Manager:
curl -u (OAUTH_CLIENT_KEY:OAUTH_CLIENT_SECRET) -k -d "grant_type=password&username=END_USER_USERNAME&password=END_USER_PASSWORD" -H "Content-Type:application/x-www-form-urlencoded" https://localhost:9443/oauth2/token
Request in API Manager to generate an access token to the API.
curl -i -X POST -u (CONSUMER_KEY:CONSUMER_SECRET) -k -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=IS_ACCESS_TOKEN' -H 'Content-Type: application/x-www-form-urlencoded' https://localhost:9444/oauth2/token
Request to API Manager to get the resource from API:
curl -v -H "Authorization: Bearer AM_ACCESS_TOKEN" http://172.19.0.1:8281/jwt/1.0.0/REST_API
Is there any easy way to accomplish these steps?
Please refer to the API security section in the documentation for more information on securing an API using roles, scopes, and tokens.
https://apim.docs.wso2.com/en/latest/learn/api-security/api-authentication/api-authentication-overview/
https://apim.docs.wso2.com/en/latest/learn/api-security/authorization/api-authorization/
This doc consists of information on how you can use different grant types with APIM and IS according to your requirements.
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 am trying to use the custom grant type client_authenticated_user of light-oauth2 token service. The reason I cannot use standard grant types is due to my client need to talk to both legacy soap API and new restful API built on top of light-rest-4j. Today the client(webserver) does the authentication for users and we want to generate a token similar with authorization code grant type by passing the user profile to light-oauth2 token service. We have both client and light-oauth2 deployed on the same organization and the client is set up trusted client type on light-oauth2 client registration.
The question is how can I access token server to get JWT token using this custom grant type as this is not a standard flow. Do you have any examples or curl commands?
As this is not a standard grant type in OAuth 2.0 specification, a lot of users are confused. To clarify this, I have created a tutorial and provide several curl command for the happy path.
https://doc.networknt.com/tutorial/oauth/custom/
I am using oAuth Model to access Podio API. I am able to generate the Access Token and Refresh Token using a pair of Client ID and Client Secret.
Later when i tried to authenticate using previously generated Access Token and Refresh Token with new pair of Client ID and Client Secret then getting Following Error Message:
{"{\"error_propagate\":false,\"error\":\"invalid_grant\",\"error_description\":\"Invalid refresh_token\",\"error_detail\":\"different_client_id\",\"request\":{\"url\":\"http://api.podio.com/oauth/token\",\"query_string\":\"\",\"method\":\"POST\"}}"}
When i tried to authenticate using same Pair of Client ID and Client secret that was originally used to generate the Access Token , it Works.
My Question is: Can we use different Client ID and Client Secret to authenticate through Access Tokens that were generated using different Client Id and Secret.
I hope i have clearly described my question.
No, access tokens are tied to a specific client and secret. Allowing access tokens to be used with other clients would be a security hole.
I have installed and configured JWT Grant Type in WSO2 IS 5.3.0 following this guide
Then I have configured a Service Provider enabling the OAuth/OpenID Connect Inbound Authenticator.
I am able from a javascript client to authenticate the user exploiting the Oauth 2 protocol with open-id scope obtaining a valid JWT token (JWTToken).
Finally I tried to make a POST request to https://****/oauth2/token?grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=JWTToken using a REST Client and setting Content-Type=application/x-www-form-urlencoded.
When I do the request the WSOIS Server asks for a username and a password. I am able to pass this step providing a valid clientId and clientSecret.
Unfortunately at this point the server dos not reply with an access token but with a 400 Bad Request and in the response body writes "{"error_description":"Error occurred while decoding public certificate of Identity Provider default for tenant domain carbon.super","error":"invalid_grant"}"
I can't understand if the problem is the JWT Token that I pass to the server or if there is some issues with the certificates. Any help please?
Okay. I think this should help you.
If you take the OpenID connect token you got from WSO2 Identity Server and put it in jwt.io you would see that the openID connect will have the "iss" (issuer) value of "https://localhost:9443/oauth2/token" (replace localhost with your hostname if you have set the hostname) which is the token endpoint of WSO2 Identity Server.
So when you use this token as a JWT Bearer grant, in order to validate the signature the grant handler tries to retrieve an IDP with the name given in the issuer(iss) field (ie. token endpoint of WSO2 Identity Server). As it fails to find any identity provider it retrieves the default identity provider (note this is a dummy IDP added for sake of backward compatibility) which doesn't have any certificate. (you can find this under $IS_HOME/repository/conf/identity/identity-providers/default.xml)
So there are two ways to fix this,
Change the issuer value of Identity Server so that it can fetch the certifcate of it's resident identity provider.
To do this,
Login to the management console,
Go to Identity Provider --> Resident --> Inbound Authentication Configuration --> OAuth2/OpenID Connect Configuration --> set the
'Identity Provider Entity Id' value as LOCAL
Create a new Identity Provider with the name equal issuer value of the OpenID connect token (ie. the token endpoint) and upload the public certificate that could be used to verify the OpenID connect token.
Personally, I prefer the first solution :)
Update:
You also need to do one more change,
In identity.xml (found under repository/conf/identity) uncomment the following lines
<Audiences>
<Audience>
${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/token
</Audience>
</Audiences>
This will make sure that the audience validation check will pass for the issued OpenID connect token when used as a JWT bearer grant. (ie. the JWT Grant handler will validate whether the token endpoint is one of the audiences in the provided grant)