I am trying to connect to an oauth2 system using guzzle but I keep getting this message:
$guzzle = new GuzzleHttp\Client;
$response = $guzzle->post('https://logincert.anaf.ro/anaf-oauth2/v1/authorize', [
'form_params' => [
'grant_type' => 'authorization_code',
'response_type' => 'token',
'client_id' => 'xxxx',
'client_secret' => 'xxxxx',
'redirect_uri' => 'http://redirect'
],
]);
return json_decode((string) $response->getBody(), true)['access_token'];
{
"error":"invalid_client",
"error_description":"The client app does not support implicit grant"
}
The provider doesn't provide much information about the returned message, the only information that they provide are:
Type: OAuth 2.0
Add Authorization Data to: Request Headers
Grant Type: Authorization Code
Callback URL: http://redirect
Authorization Endpoint: https://logincert.anaf.ro/anaf-oauth2/v1/authorize
Token Endpoint: https://logincert.anaf.ro/anaf-oauth2/v1/token
Token Revocation Endpoint: https://logincert.anaf.ro/anaf-oauth2/v1/revoke
Client ID: xxx
Client Secret: xxx
Client Authentication type: Send as Basic Auth header
Any ideas what am I doing wrong?
Thanks,
Chris
Related
I am calling one Microsoft graph API from my PHP application, API is https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy
my code is like below
$graph = new Graph();
$graph->setAccessToken(session('my_token'));
try{
$response = $graph->createRequest("GET", "/policies/identitySecurityDefaultsEnforcementPolicy")->execute();
}
catch(Exception $e){
dd($e);
}
$arr = $response->getBody();
dd($arr);
but it always catches exception and displays the below error
Client error: `GET https://graph.microsoft.com/v1.0/policies/identitySecurityDefaultsEnforcementPolicy` resulted in a `403 Forbidden` response:
{"error":{"code":"AccessDenied","message":"You cannot perform the requested operation, required scopes are missing in the token.","innerError":{"date":"2022-11-23T06:47:39","request-id":"9a4573c7-fd72-44ae-8ac6-8e4589cf1497","client-request-id":"9a4573c7-fd72-44ae-8ac6-8e4589cf1497"}}}
all the other Microsoft graph APIs are working well
I have also given permission to Policy.Read.All and granted admin consent to the Microsoft app I am using here for auth.
Update: when I open Microsoft's online token parser https://jwt.ms/ and parsed my token, I see the roles like
"roles": [
"Mail.ReadWrite",
"User.ReadWrite.All",
"SecurityEvents.Read.All",
"Mail.ReadBasic.All",
"Group.Read.All",
"MailboxSettings.Read",
"Group.ReadWrite.All",
"SecurityEvents.ReadWrite.All",
"User.Invite.All",
"Directory.Read.All",
"User.Read.All",
"Domain.Read.All",
"GroupMember.Read.All",
"Mail.Read",
"User.Export.All",
"IdentityRiskyUser.Read.All",
"Mail.Send",
"User.ManageIdentities.All",
"MailboxSettings.ReadWrite",
"Organization.Read.All",
"GroupMember.ReadWrite.All",
"IdentityRiskEvent.Read.All",
"Mail.ReadBasic",
"Reports.Read.All"
]
but not the Policy.Read.All
Update: Getting auth token code is
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/'.env("TANANT_ID").'/oauth2/token?api-version=beta';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => env("CLIENT_ID"),
'client_secret' => env("CLIENT_SECRET"),
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
// echo $token->access_token;
Session::put('my_token', $token->access_token);
When you're requesting the token, you need to supply a scope URL,
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#get-a-token
So as a basic example (this might not give the permission you need) but shows what your missing.
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/'.env("TANANT_ID").'/oauth2/token?api-version=beta';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => env("CLIENT_ID"),
'client_secret' => env("CLIENT_SECRET"),
'resource' => 'https://graph.microsoft.com/',
'scope' => 'https://graph.microsoft.com/.default',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
// echo $token->access_token;
Session::put('my_token', $token->access_token);
specifically notice that i have added
'scope' => 'https://graph.microsoft.com/.default', to your form params
Looks like you don't have Policy.Read.All permission , could you please cross check permission through azure portal and provide the required permission and try again.
Thanks
I'm redirecting my user to Cognito hosted UI, then returning to my PHP application. If the code is found then I use Guzzle to exchange this with the access tokens, however I keep on receiving the following error:
{"error":"unauthorized_client"}
This is my code, I have double checked what i'm passing in with the documentation and it all looks fine to me!
if ($code = request()->input('code')) {
$client = new Client();
$confirmCodeDomain = "https://$domain/oauth2/token";
try {
$result = $client->post($confirmCodeDomain, [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $client_id,
'code' => $code,
'redirect_uri' => 'https://localhost/auth/',
],
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => 'Basic '.base64_encode("$client_id:$client_secret")
]
]);
} catch (\Exception $e) {
dd($e);
}
dd($result);
}
This is my serverless file which creates the AWS resources required, the error states:
unauthorized_client
Client is not allowed for code grant flow or for refreshing tokens.
However as you can see from my client definition the AllowedOAuthFlows is set to code:
resources:
Resources:
CognitoEmployeePool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: employees
MfaConfiguration: OFF
AdminCreateUserConfig:
AllowAdminCreateUserOnly: true
Policies:
PasswordPolicy:
MinimumLength: 7
RequireLowercase: true
RequireUppercase: true
RequireNumbers: false
RequireSymbols: false
EmailConfiguration:
EmailSendingAccount: "COGNITO_DEFAULT"
UsernameAttributes:
- email
AutoVerifiedAttributes:
- email
CognitoEmployeePoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: employees-webplanner
CallbackURLs:
- "https://localhost"
- "https://localhost/auth"
AllowedOAuthFlowsUserPoolClient: true
SupportedIdentityProviders:
- "COGNITO"
AllowedOAuthFlows:
- "code"
AllowedOAuthScopes:
- "openid"
- "email"
UserPoolId:
Ref: CognitoEmployeePool
ExplicitAuthFlows:
- ALLOW_ADMIN_USER_PASSWORD_AUTH
- ALLOW_REFRESH_TOKEN_AUTH
- ALLOW_USER_PASSWORD_AUTH
GenerateSecret: true
CognitoEmployeePoolDomain:
Type: AWS::Cognito::UserPoolDomain
Properties:
UserPoolId: !Ref CognitoEmployeePool
Domain: "marvs-sso"
Create users in keycloak in his realm in PHP.
I created myself in the interface admin a realm which is named "myreal", then I created a user who is named "Myuser".
I would like my "Myuser" user to be able to create other users in his realm.
For that I did like this:
$response = $client->request('POST', 'http://localhost:8080/auth/admin/realms/myrealm/users', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer '.$accessToken->getToken(),
'form_params' => [
'username' => 'test',
],
],
]);
$accessToken -> it's the token of "Myuser".
My user has the client role "realm-management" with Assigned Roles -> manage-users
I have as a return an error:
Client error: `GET http://localhost:8080/auth/admin/realms/myrealm/users` resulted in a `403 Forbidden` response
To use Microsoft Graph, I'm trying to authenticate on behalf of the user. I'm following this tutorial, and I'm currently stuck at step 3.
When requesting the token, I receive a 400 Bad Request response:
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided request must include a 'scope' input parameter."
}
Even though I'm including a scope parameter, this is my request:
$guzzle = new \GuzzleHttp\Client(['headers' => [
'Host' => 'https://login.microsoftonline.com',
'Content-Type' => 'application/x-www-form-urlencoded'
]
]);
$url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => '################################',
'scope' => 'user.read%20mail.read',
'code' => $_GET['code'],
'grant_type' => 'authorization_code',
'redirect_uri' => 'https://eb3ef49e.ngrok.io/callback.php',
'client_secret' => '################'
],
])->getBody()->getContents());
What am I doing wrong?
I guess the complete error description says:
AADSTS70011: The provided request must include a 'scope' input
parameter. The provided value for the input parameter 'scope' is not
valid. The scope user.read%20mail.read is not valid. The scope
format is invalid. Scope must be in a valid URI form
<https://example/scope> or a valid Guid <guid/scope>.
If so, then Azure AD endpoint could not recognize the provided scope here. /token endpoint expects scope parameter to be specified as a space-separated list of scopes . Meaning there is no need to explicitly escape space symbol here:
'scope' => 'user.read%20mail.read'
instead specify it like this:
'scope' => 'user.read mail.read'
and and Guzzle client will do the rest of constructing the encoded body for /token endpoint
Trying to wrap my head around using Laravel's Passport with mobile clients. The Password Grant type of authentication seems to be the way to go, and i have it working with my iOS app, however i can't get token refreshing to work.
When authenticating i get a token and a refresh token which i store, however when the token expires, calling the oauth/token/refresh route doesn't work. The route is using the web middleware which means my app using the api route can't access it. I'm not sure if they intended for mobile clients to never refresh or if they wanted you to roll your own refreshing? If anyone has insight on how this is supposed to work, that'd be great.
The oauth/token/refresh route is not for refreshing access tokens. It is used to refresh transient tokens, which are used when you consume your own API from your javascript.
To use your refresh_token to refresh your access token, you need to call the oauth/token route with the grant_type of refresh_token.
This is the example provided by the documentation:
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
One note about scopes, when you refresh the token, you can only obtain identical or narrower scopes than the original access token. If you attempt to get a scope that was not provided by the original access token, you will get an error.
I've done something like.
Created an endpoint for grant refresh token.
and in my controller,
public function userRefreshToken(Request $request)
{
$client = DB::table('oauth_clients')
->where('password_client', true)
->first();
$data = [
'grant_type' => 'refresh_token',
'refresh_token' => $request->refresh_token,
'client_id' => $client->id,
'client_secret' => $client->secret,
'scope' => ''
];
$request = Request::create('/oauth/token', 'POST', $data);
$content = json_decode(app()->handle($request)->getContent());
return response()->json([
'error' => false,
'data' => [
'meta' => [
'token' => $content->access_token,
'refresh_token' => $content->refresh_token,
'type' => 'Bearer'
]
]
], Response::HTTP_OK);
}