I would like to programmatically register confidential OIDC client (the client is a backend service). I checked the keycloak document about it. And I use the “Initial access token“ approach as recommended.
After I created a "initial access token" on the UI console, I register a new client by:
POST https://my-keycloak-host/auth/realms/MyRealm/clients-registrations/default
Headers: Authorization: Bearer <initial access token>
{ "clientId": "my-client" }
The response contains a registrationAccessToken. But I expect to get a client secret. How can I get it? And what is the usage for that registrationAccessToken?
For some unknown reason Keycloak doesn't set secret properly. But you can define own secret with secret property in the payload (tested with Keycloak 16.1.1), e.g.:
{
"clientId": "my-client",
"secret": "my-secret"
}
Doc:
https://openid.net/specs/openid-connect-registration-1_0.html
https://www.keycloak.org/docs/latest/securing_apps/index.html#_client_registration
I am following the documentation posted here (https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops).
I have a react-based webapp and a powershell-based function app, both in Azure. My function app is presently using a personal access token created with my work account (AAD) credentials, which is not desirable. My goal is to use OAuth2 to authorize my function app to make code changes to a GIT repository on behalf of a webapp user. When I follow the instructions above, I am able to acquire what appears to be a valid authorization code, access token, and refresh token, I receive the following error message from Azure DevOps:
TF400813: The user 'ffffffff-ffff-ffff-ffff-ffffffffffff' is not authorized to access this resource.
…
401 - Uh-oh, you do not have access.
The request requires authentication.
4/21/2021 12:04:16 AM (UTC)
ffffffff-ffff-ffff-ffff-ffffffffffff
Sign out and login with different account
I have obscured the guids in the example above, but the user GUID appears to match the GUID I find for my work account when I call the legacy identity APIs (https://learn.microsoft.com/en-us/rest/api/azure/devops/ims/identities/read%20identities?view=azure-devops-rest-6.0).
I created my application (https://app.vsaex.visualstudio.com/app/register) with the same scopes that I used to create my personal access token. I verified in my dev.azure.com profile that my application is listed as an authorized OAuth app, as expected after creating the authorization request and receiving the authorization code.
The error message above is confusing to me. It says that the user (me) is not authorized to access the resource but also says that the authentication failed. Which is it?
Is this a problem with how I am acquiring my authorization/access tokens? Am I somehow using the wrong account? Are my scopes wrong?
Reproduction of Problem
Here is the state from my registered application:
My application state:
{
"scopes": "vso.code_full vso.code_status vso.graph_manage vso.identity_manage vso.threads_full vso.tokens",
"tokenUrl": "https://app.vssps.visualstudio.com/oauth2/token",
"state": "foo",
"authCallback": "https://myapp.azurewebsites.net/oauth-callback",
"clientSecret": "S.S.S-S-S",
"authUrl": "https://app.vssps.visualstudio.com/oauth2/authorize",
"appWebsite": "https://myapp.azurewebsites.net/",
"appSecret": "S",
"appId": "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"
}
Step 1. Authorize the application.
I invoke the following auth URI from an in-private browser.
I authenticate my work account, and authorize the application for the requested scopes.
I can verify the app is an authorized oauth app in my dev.azure.com profile.
https://app.vssps.visualstudio.com/oauth2/authorize?client_id=FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF&response_type=Assertion&state=foo&scope=vso.code_full%20vso.code_status%20vso.graph_manage%20vso.identity_manage%20vso.threads_full%20vso.tokens&redirect_uri=https://myapp.azurewebsites.net/oauth-callback
I receive an authcode, "A.A.A-A-A-A" (shown decoded/obfuscated below):
{
"typ": "JWT",
"alg": "RS256",
"x5t": "....."
}
{
"cid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"csi": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"nameid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"iss": "app.vstoken.visualstudio.com",
"aud": "app.vstoken.visualstudio.com",
"nbf": 1618438026,
"exp": 1776204426
}
Step 2. Request the access token and refresh token from my powershell function app:
I make a rest api call to the token endpoint:
"Uri": "https://app.vssps.visualstudio.com/oauth2/token"
"Method": "POST"
"ContentType": "application/x-www-form-urlencoded"
"Body": "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=S.S.S-S-S&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=A.A.A-A-A-A&redirect_uri=https://myapp.azurewebsites.net/oauth-callback"
…and I get the following JSON response:
Token Response:
{
"access_token": "X.X.X-X-X-X-X-X-X",
"token_type": "jwt-bearer"
"expires_in": 3599,
"refresh_token": "R.R.R-R-R-R",
"scope": "vso.code_full vso.code_status vso.graph_manage vso.identity_manage vso.threads_full vso.tokens vso.authorization_grant"
}
Yielding the following JWT for the access token:
{
"typ": "JWT",
"alg": "RS256",
"x5t": "....."
}
{
"nameid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"scp": "vso.code_full vso.code_status vso.graph_manage vso.identity_manage vso.threads_full vso.tokens",
"aui": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"appid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"iss": "app.vstoken.visualstudio.com",
"aud": "app.vstoken.visualstudio.com",
"nbf": 1618963456,
"exp": 1618967056
}
Step 3. Make a DevOps REST API call.
In this case, I am requesting a list of respositories in my org/project:
"Uri": "https://dev.azure.com/myorg/myproj/_apis/git/repositories?api-version=6.0"
"Method": "GET"
"Headers": {"Authorization": "Bearer X.X.X-X-X-X-X-X-X"}
This is where things go wrong. DevOps returns a 401 error indicating that my account is not authorized.
TF400813: The user 'ffffffff-ffff-ffff-ffff-ffffffffffff' is not authorized to access this resource.
If I make the exact same http GET from Step 3, but I substitute my PAT with identical scopes as the registered application, the call succeeds. The PAT seems to be created with the exact same profile/account that is authorized in Step 1.
This behavior can be observed when the organization admins have disabled OAuth in the settings. The relevant option can be viewed by any member of the org at e.g. https://dev.azure.com/contoso/_settings/organizationPolicy
Sadly there is no better indication of this for the app or the user, as far as I can see.
Your app can still ask the user for authorization, all OAuth operations succeed, a seemingly valid access token gets returned, but then it simply does not work and returns 401 from all APIs, even if a PAT with the same scope(s) works fine.
I followed the guide of PayPal: https://developer.paypal.com/docs/platforms/get-started/
and made a request to https://api.sandbox.paypal.com/v1/oauth2/token to obtain an access token.
This works totally fine.
Now I want to do the following request: https://api.sandbox.paypal.com/v1/payments/payment
(Selecting Bearer Auth in Postman, using the token I obtained in the request before)
Now I get the following error response:
{
"name": "REQUIRED_SCOPE_MISSING",
"message": "Access token does not have required scope",
"information_link": "https://developer.paypal.com/docs/api/payments/#errors",
"debug_id": "548db8d53cfde"
}
Yes, I configured my project to allow such things:
App configuration
I really appreciate any help.
EDITED:
Response from: https://api.sandbox.paypal.com/v1/oauth2/token
{
"scope": "https://uri.paypal.com/services/invoicing https://uri.paypal.com/services/disputes/read-buyer https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/disputes/update-seller https://uri.paypal.com/services/paypalhere https://uri.paypal.com/services/payments/payment/authcapture openid https://uri.paypal.com/services/disputes/read-seller https://uri.paypal.com/services/payments/refund https://uri.paypal.com/services/identity/activities https://api.paypal.com/v1/vault/credit-card https://api.paypal.com/v1/payments/.* https://uri.paypal.com/payments/payouts https://api.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/subscriptions https://uri.paypal.com/services/applications/webhooks https://api.paypal.com/v1/payments/refund https://api.paypal.com/v1/payments/sale/.*/refund",
"token_type": "Bearer",
"expires_in": 30189
}
There's no actual issue with your scopes, all are there.
It seems your payment request to https://api.sandbox.paypal.com/v1/payments/payment is incomplete
See here for an example guide for creating a payment: https://developer.paypal.com/docs/integration/direct/payments/paypal-payments/#create-paypal-payment
Be sure to pass a transaction object with an amount, and any other required parameters
I'm trying to use DialogFlow REST API with api key auth method. For example
https://dialogflow.googleapis.com/v2/projects/projectId/agent?key=[YOUR_API_KEY]
but It desn't work. This is the result
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
I'm trying to implement the forgot password flow with key-cloak and was able to do it with key-cloak admin UI. But now I want to do this reset flow completely inside the web application without forwarding the user to key-cloak. By observing the reset token (action token) sent to the email it shows it has attributes such as type and expiry.
{
"jti": "xx",
"exp": 1553850003,
"nbf": 0,
"iat": 1553846403,
"iss": "xxx",
"aud": "xxx",
"sub": "6eabb442-d40d-4857-8b8f-xxx",
"typ": "reset-credentials",
"nonce": "xxx",
"asid": "xxxx"
}
The admin Api provides an api to reset password but I cannot find an api to obtain an action token/forgot password api. Would be much obliged if I could know how to approach this workflow with key-cloak admin.