Allow support of Grant Type "Client Credentials"
Problem this snippet solves:
The OAuth 2.0 framework specifies several grant types for different use cases (for more information about grant type: https://oauth.net/2/grant-types/).
The "Client Credentials" grant type is used by clients to obtain an access token outside of the context of a user. This is typically used by clients to access resources about themselves rather than to access a user's resources.
Typically the service will allow either additional request parameters client_id and client_secret, or accept the client ID and secret in the HTTP Basic auth header. The POST request that the application makes looks like the example below:
POST /f5-oauth2/v1/token HTTP/1.1 Host: as.mydomain.com grant_type=client_credentials client_id=ds87as7f5dasdsa890dfd0fdsd7685dsfd98d9f8s98fs client_secret=vfv998dsa7697fd900d96fd876d765a54a7s5dsfd798d
however as you can noticed F5 does not provide this grant_types (Client Credentials) for client application.
How to use this snippet:
s explaind above, F5 does not provide "Client Credentials" but provide "Resource Owner Password Credentials".
Resource Owner Password Credentials is used by first-party clients to exchange a user's credentials for an access token. the user's username and password are exchanged directly for an access token. the application presents a traditional username and password login form to collect the user’s credentials and makes a POST request to the server to exchange the password for an access token. The POST request that the application makes looks like the example below:
POST /f5-oauth2/v1/token HTTP/1.1 Host: as.mydomain.com grant_type=password username=user password=mypwd client_id=ds87as7f5dasdsa890dfd0fdsd7685dsfd98d9f8s98fs client_secret=vfv998dsa7697fd900d96fd876d765a54a7s5dsfd798d
So as you can noticed, "Client Credentials" and "Resource Owner Password Credentials" Request are substantially similar. the only difference is that we add the parameter username and password in addition. And grant_type name is different (password / client_credentials).
So If Client imposes "Client Credentials" grant type, follow this procedure to achieve your need.
in your client application settings checked "Resource Owner Password Credentials"
Access ›› Federation : OAuth Authorization Server : Client Application
As you can notided below in the irule, we retwrite only request done by the client:
Code :
when HTTP_REQUEST { set grant_type null if { ( [string tolower [HTTP::uri]] equals "/f5-oauth2/v1/token" ) and ( [HTTP::method] equals "POST" ) } { set grant_type "client_credentials" HTTP::collect [HTTP::header Content-Length] } } when HTTP_REQUEST_DATA { if {$grant_type contains "client_credentials" } { set payload [HTTP::payload] if { [HTTP::payload] contains "grant_type=client_credentials" } { # log local0. "Old Payload: [HTTP::payload]" HTTP::payload replace 0 0 [string map {"grant_type=client_credentials" "grant_type=password&username=test&password=jhgkhlkjhkjhkj"} $payload] # log local0. "New Payload: [HTTP::payload]" HTTP::release } } } # For information (both request): #grant_type=password&username=test&password=jhgkhlkjhkjhkj&scope=username&client_id=ds87as7f5dasdsa890dfd0fdsd7685dsfd98d9f8s98fs&client_secret=vfv998dsa7697fd900d96fd876d765a54a7s5dsfd798d #grant_type=client_credentials&scope=username&client_id=ds87as7f5dasdsa890dfd0fdsd7685dsfd98d9f8s98fs&client_secret=vfv998dsa7697fd900d96fd876d765a54a7s5dsfd798d
Tested this on version:
13.0- Roger_245191Nimbostratus
I think there is a mistake with this part of the irule:
HTTP::payload replace 0 0 [string map {"grant_type=client_credentials" "grant_type=password&username=test&password=jhgkhlkjhkjhkj"} $payload]
It should actually be something like this:
HTTP::payload replace 0 [HTTP::payload length] [string map {"grant_type=client_credentials" "grant_type=password&username=test&password=jhgkhlkjhkjhkj"} $payload]
This is important because if grant_type isn't the first argument in the call, it simply won't work.
- Sam_D_Altostratus
Instead of adding these tweaks and twists on our iRules, I'm just wondering why BigIP will not add support of the Client Credentials Grant Type since it is pretty useful in term of securing external APIs