How to create Okta Custom Policy in Mulesoft API Manager? - oauth-2.0

I want to create an custom policy to implement Okta OAuth in Mulesoft. Same thing has been done before in Mule, but I cannot find the source, please see this video, 5Minute-Youtube-Video
I want to achieve the same thing, as shown in video.
How to create the XML configuration for the following YAML?
name: Custom Okta Policy Example
description: Using external Okta to provide OAuth.
category: Security
standalone: true
providedCharacteristics: [Message protection]
requiredCharacteristics: []
requiresConnectivity: true
configuration:
- propertyName: url
name: Okta Organization URL
description: Enter the developer portal URL
type: string
optional: false
defaultValue: http://dev-7482-admin.oktapreview.com
- propertyName: clientId
name: Client ID
description: Okta Application client id
type: string
defaultValue: 0oabdnelyuUcFe0h7
optional: false
- propertyName: clientSecret
name: Client Secret
description: Okta Application client secret
type: string
defaultValue: FUcZlNfYd0XmExqp1xjbxVbFpp2z81ospOz8iH
optional: false

For the oAuth token enforcement custom policy for a third party oAuth provider, you may create one based on the one used by Mule's oAuth provider (see here). Just apply the policy, see what's downloaded in the policies folder of the runtime, and base your custom policy on it. Notice that you will want to remove the client ID enforcement part, since used the client ID and secrets are generated outside Anypoint API Platform.
On the other side, if you only would like to have Okta oAuth 2.0 support, you may leverage their OpenID Connect protocol just by configuring your organization and applying the corresponding out-of-the-box policy.

Related

Installed Yii2-Oauth2-Server. Need help trying to describe the steps customers need to take for authorization

I've installed the Yii2-Oauth2-Server on my server for customers to authenticate their apps in order to use my API. Event though I know very little about the Oauth2 protocol, everything works correctly when I test it in Postman using the information in the documentation.
Now I need to write some documentation for my customers describing how to authorize their apps but I'm not sure what to say. What information do they need from me? What data do they need to provide to me for this to work?
Here is what I have entered in Postman.
Grant Type: Authorization Code (With PKCE)
Callback URL: <blank> (Authorize using browser)
Auth URL: https://example.com/oauth2/authorize
Access Token URL: https://example.com/oauth2/access-token
Client ID: postman-sample-client
Client Secret: your-client-secret
Code Challenge Method: SHA-256
Code Verifier: <Automatically generated if left blank>
Client Authentication: <Send as Basic Auth header>

PowerApps : Custom Connector with MS Graph : How can I use Application permissions in my custom connector?

I am having trouble creating a PowerApps Custom Connector which allows me to access Microsoft Graph using APPLICATION permissions.
I have created my Azure AD App Registration, with three API permissions:
Delegated: User.Read
Application: User.Read.All
Application: Directory.Read.All
I have confirmed the Redirect URI is correctly set for Power Apps (https://global.consent.azure-apim.net/redirect) and I have generated a Client Secret.
I have then created TWO different Power Apps custom connectors, and both of them give me exactly the same results.
Connector A: Auth Type: OAuth2.0
Identity Provider: Generic OAuth 2
Client ID & Client Secret (as expected)
Auth URL: https://login.microsoftonline.com/{{Tenant ID}/oauth2/v2.0/authorize
Token URL: https://login.microsoftonline.com/{{Tenant ID}/oauth2/v2.0/token
Scope: https://graph.microsoft.com/.default
Connector B: Auth Type: OAuth 2.0
Identify Provider: Azure Active Directory
Client ID & Client Secret (as expected)
Login URL: https://login.windows.net
Tenant ID: common (this is the default)
Resource URL: https://graph.microsoft.com
Scope: {blank} (this is the default)
I then setup (in both connectors) the same two actions:
/v1.0/me
/v1.0/users
In BOTH connectors the first action (/me) works .. and returns the details of the logged in user.
The second connector (/users) returns "Access Denied - Insufficient Privileges".
This is telling me it is using the Delegated permissions (which allows it to retrieve /me) and not the Application permissions (which is why it can't list all of the user accounts).
So .. is there any setting in Power Apps which allows me to specify that this connector should use Application requests rather than delegated?
Thank you!

Authenticate Azure API Management with OAuth2 using Azure AD

I am trying to secure APIM APIs using OAuth2 via AzureAD by reading the article: Protect a web API backend in Azure API Management by using OAuth 2.0 authorization with Azure AD
AzureAPIM - OAuth2
Authorization endpoint URL (v1): https://login.microsoftonline.com/{tenant}/oauth2/authorize
Token endpoint URL (v1): https://login.microsoftonline.com/{tenant}/oauth2/token
Client ID: client-app id
Redirect URI: (deprecated portal): https://xxx-api.portal.azure-api.net/docs/services/auth1/console/oauth2/authorizationcode/callback
AzureAD - backend-app:
scope: Files.All
AzureAD - client-app:
secret key: xxx
Redirect url: ONLY WORK with deprecated portal in APIM (https://xxx-api.portal.azure-api.net/docs/services/auth1/console/oauth2/authorizationcode/callback)
For Demo Conference API, Add Validate JWT policy to Inbound processing where 3a0cf09b- is tenant id and b7c31179- is backend-app application id:
In Developer portal, the authentication to AzureAD is successful with a return token:
However the authorization is failed with calling the API:
Inspecting the received token in jwt.io, I found that the "aud": "00000003-0000-0000-c000-000000000000" is not backend-app application id:
{
"aud": "00000003-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/3a0cf09b-xxx/",
"app_displayname": "client-app",
"appid": "05a245fb-xxx",
"scp": "Files.Read User.Read profile openid email",
"tenant_region_scope": "OC",
"tid": "3a0cf09b-2952-4673-9ace-0e1bf69ee23a",
"unique_name": "user1#xxx.onmicrosoft.com",
}
API Test HTTP response trace shows the error on validate-jwt:
validate-jwt (-0.138 ms)
{
"message": "JWT Validation Failed: Claim value mismatch: aud=b7c31179-xxx.."
}
Replacing aud by the value in the token 00000003-0000-0000-c000-000000000000 or removing the required-claims in the validate-jwt policy to get it working.
Any idea please?
From your error report, it is indeed a 401 error, that is, your aud does not match the api you want to call, I use the auth code flow to do a simple demonstration for you:
First expose the api of the back-end application and add the client application.
Next,under 'API permissions', give your front-end application access to your backend api:
Under 'API permissions' click on 'Add permission', then click on the 'My APIs' tab.
Find your backend application and select the appropriate scope.
Click 'Add permissions'.
Grant admin consent for your APIs.
Get token:
Parse the token:
It seems you choose v1 endpoint of OAuth2 authorization but not v2 endpoint, so the value of aud in access token should be like b7c31179-xxxx.... but not api://b7c31179-xxxx..... So there are no mistakes in your steps of get access token.
According to some test in my side, the cause of this problem is you did not specify a parameter resource with the value of the backend-app application id when you configure OAuth2.0 in your APIM. The document you refer to also mentions this (I test with not specify this parameter, it shows same problem with yours)
So to solve this problem, please go to your APIM and click "OAuth 2.0" tab, edit the item you created. Add a parameter resource with value of the backend-app application id.
Note: When you add the parameter resource and click "Save" button, please open the item again and check if the "Client secret" box is empty. When I test in my side, the "Client secret" box shows empty after add parameter resource, it may be a bug on that page. If "Client secret" is empty, it might show error message like The request body must contain the following parameter: 'client_assertion' or 'client_secret' when you get the access token in Developer portal.

How to connect custom API using own OAuth2 in Microsoft Power Automate?

I've been trying to connect Microsoft Power Automate to my API. My API has a OAuth2 Code Flow.
According to Power Automate, the connector can make a connection to my API. and execute a test. But the problem is that Microsoft sends a Bearer token that was generated by them, and not the one that I gave to them via OAuth2, resuting on my API giving a 401 Error (Invalid Token) as expected.
In the Power Automate Custom Connector page, in the security tab I have the following:
Authentication type
OAuth2.0
OAuth2.0 Settings
Identity Provider: Generic OAuth2
Client ID: SomeValue
ClientSecrect: SomeValue
Authorization URL: mydomain.com/auth/authorize
Token URL: mydomain.com/auth/token
Refresh URL mydomain.com/auth/token
Redirect URL: microsoft-flow.com/redirect (Not the real one)
When Microsoft makes a POST request to mydomain.com/auth/token, I return the following body:
{
access_token: "non JWT token", // simillar to a hash
refresh_token: "non JWT token",
expires_in: 3600
}
The request above is final request that microsoft before accepting as a valid connection. The token that microsoft sends me is a JWT one, not the one I provided.
I've seen some guys using Azure AD authentication within the APP, but I was trying to implement something simillar to other platoforms(e.g Github, Spotify, e.t.c)
So my question is it possible to connect Power Automate to a custom API with using OAuth2? If yes, how to do it?
It's possible.
In addition to the OAuth2.0 Settings you listed, there is another important property Scope which you have missed.
Since your API is protected in Azure AD, so I assume that you have created an Azure AD app for your API and exposed scopes.
After that, you can get the application ID URI (api://{clientId}) for your API.
You should put this value into the "Scope" in Power Automate, like this:
Then this access token will be considered valid by your API.
I've done two steps to fix this problem.
Step 1
Previously my API returned the body with access_token, refresh_token and expires_in, but then I added scope and token_type. Example:
{
access_token: "2346ad27d7568ba9896f1b7da6b5991251debdf2",
refresh_token: "4468e5deabf5e6d0740cd1a77df56f67093ec943",
expires_in: 3600,
scope: "none",
token_type: "Bearer"
}
Step 2
Delete the custom connector and create a new one with the same parameters. When I got to the "Test" section, Power automate finally could make the GET request successfully.
In my case, even if the the API was updated, Power automate was still using its faulty token, so I had to delete that custom connector and create new one.
Conclusion
By updating the API and deleting the old custom connector, I was able to get the connector working.

Securing Public APIs using Authorization Code flow in IdentityServer 4

I am stuck with one very basic requirement in my application. Here is my scenario. I am building a custom e-commerce portal using angular as a front end and rest API as a back end. I have a product listing API that is going to be called by my angular client application without the user's credentials as the product listing is a public page. However, I don't want anyone else to consume my product listing API. I know I can use client id and client secret to obtain token and make my API secure using Identityserver 4 but, how do I avoid exposing my client secret in an angular app?
Anyone can steal it very easily. Is there any way to use Authorization Code flow with PKCE for public my APIs such as product listing API where user id and password are not required?
To me best approach to answer this is to go back to definition of Authorization Code flow.Authorization code grant is a redirection-based flow used to obtain both access tokens and refresh tokens, the client initiates the flow by directing the resource owner's.
And pkce is just is an extension to the Authorization Code flow to prevent certain attacks.
Then the answer is no, we can not use Authorization Code flow with PKCE to secure a public API without user login.
There is some other ways to secure public APIs or at least make it less/harder accessible. CORS is an option, read more here, as its out of context for this question I wouldn't go further.
For scenario with login, Authorization code flow is supported on IdentityServer4. here is what we need to do to implement it:
On IdentityServer add the configuration entry for js client like:
new Client
{
ClientId = "jsclient",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
RedirectUris = { "http://localhost:5003/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
AllowedCorsOrigins =
{
"http://localhost:5003"
},
AllowedScopes = {"openid", "profile", "offline_access", "api1", "api2" },
}
On SPA app use oidc-client library, and also add the OIDC config to be like
var config = {
authority: "http://localhost:5000",
client_id: "js",
redirect_uri: "http://localhost:5003/callback.html",
response_type: "code",
scope:"openid profile api1",
post_logout_redirect_uri : "http://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);
Find full sample code here. I strongly suggest to read the quickstart doc to get a better understanding of implementation details.
You should implement Authorization Code Flow (PKCE) in your Angular App by plugging in the widely used OIDC Client library - its UserManager class will do the work for you.
For an example of how to use it, see these resources of mine:
Visual Tutorial Write Up
Code Sample
Authorization Code Flow PKCE Code

Resources