Error when getting token using BotFramework's OAuthPrompt and Azure Oauth 2 Generic Provider - azure

I'm trying to add authentication to a bot for Microsoft Teams using the Azure Oauth 2 Generic Provider. It works the first time I sign in, but if I need to get the token again, bot framework raises an error.
The connection works fine when I test in Azure Portal
Azure Portal connection test
And the token is returned the first time I call OAuthPrompt and sign in, I'm able to get the user profile as expected:
OAuthPrompt token response
If I call OAuthPrompt a second time to get the token, I get the error DialogContextError: Error retrieving token: 3498ec40d9ccd8469840bd31f8b1a78c.
The code for the dialog:
this.addDialog(
new OAuthPrompt(OAUTH_PROMPT, {
connectionName,
text: "Please sign in",
title: "Sign in",
timeout: 300000,
showSignInLink: true
})
);
How I get the token:
private async getTokenStep(stepContext: WaterfallStepContext) {
return await stepContext.beginDialog(OAUTH_PROMPT);
}
Any Idea what I doing wrong?

If you are using the OAuthPrompt class provided by MS, the most obvious reason I can think of that it's generating an error retrieving the token is because your request is getting throttled. If you can find the HTTP Request in your debug it's most likely returning 400 Bad Request.
Why are you calling the OAuthPrompt the second time to generate a new token, when you already requested a token the first time? What you should actually be doing is saving the token you generated from the first request into a user state, and reusing the token until it expires. You can check if the token expires before prompting for a new token again.
Check this article for how to save user state.
https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-state?view=azure-bot-service-4.0&tabs=csharp

Related

Cannot make Azure B2C refersh token become invalid

When a user logs out of Azure B2C using the MSAL library on a mobile device this only clears the local cache. The remote session on the server still exists which means any existing refresh tokens could still be used.
From searching I know that the Microsoft Graph API can be used to revoke the current user's sign in session, and therefore invalidate all current refresh tokens. I believe I am doing this, but the refresh tokens keep remaining active.
Here is my flow:
I get a token for user A (I tried this with auth code flow and ROPC but I don't believe that should make a differnce).
I confirmed that I can get a new access token by using the current refresh token that is returned in a Postman call -
{{b2c_login_url}}/B2C_1_ROPC_SignIn/oauth2/v2.0/token?grant_type=refresh_token&client_id={{b2c_ropc_client_id}}&refresh_token=xxxxx&scope={{b2c_scopes}}&redirect_uri={{b2c_api_redirect_uri}}
This returns a new access token as expected.
I then take the azure userId value ("oid" property in the access token) and pass that through to my API that then runs the following code.
var graphClient = GetGraphClient();
var result = await graphClient.Users["{" + userId + "}"]
.RevokeSignInSessions()
.Request()
.PostAsync();
return result.GetValueOrDefault();
I can see that the result of this expression is true. I can also go onto the Azure B2C user details and see that "StsRefreshTokensValidFrom" has been updated to the current date time as expected.
Now, I run the exact same http request I ran previously using the refresh token to get another access token, but this time, it should fail. However, I continue to get new access tokens.
The strange thing is that I am sure I tested this previously, tried to get a new token, and it failed as I'd expect. But now it will always return me new tokens.
I feel I am missing something here. Any advice?
I tried to reproduce the same in my environment and got below results:
I generated token for a B2C user using ROPC flow via Postman with parameters as below:
POST https://<tenant_name>.b2clogin.com/<tenant_name>.onmicrosoft.com/<policy>/oauth2/v2.0/token
client_id : xxxxx-xxxx-xxxx-xxxxxxxx
grant_type : password
scope : https://<tenant_name>.onmicrosoft.com/web_api/api.read offline_access
username : b2c_username
password : password
Response:
Using the above refresh token, I'm able to generate access token successfully like below:
POST https://<tenant_name>.b2clogin.com/<tenant_name>.onmicrosoft.com/<policy>/oauth2/v2.0/token
client_id : xxxxx-xxxx-xxxx-xxxxxxxx
grant_type:refresh_token
scope:https://<tenant_name>.onmicrosoft.com/web_api/api.read
redirect_uri:https://jwt.ms
refresh_token:paste_refresh_token
Response:
To revoke refresh tokens, I ran below query via Graph Explorer like this:
POST https://graph.microsoft.com/beta/users/<user_id>/invalidateAllRefreshTokens
Response:
Code Sample in C#:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
await graphClient.Users["userid"]
.InvalidateAllRefreshTokens()
.Request()
.PostAsync();
To confirm that, I checked user's details in Portal like below:
When I tried to get access token with same refresh token, I got error saying token is revoked like below:
After revoking the tokens from Graph API, it may take up to 5 minutes to work.
If you run the query for access token as soon as you revoked the refresh tokens, you may still get access token.
So, wait for 5-10 minutes and try to get the access token with same query. Then, you won't be getting access token as the refresh token will be revoked at that time.

error 401 unauthorized I see when I am successfully logged in. But after logging in, the token gets Revoked and the response is error 401 unauthorized

that error appears to me
[Unhandled promise rejection: Error: Request failed with status code 401]
that's the Ropo link
https://github.com/ahmedsawy1/Carna-Project
It contains two folders, the first for the front end (React Native) and the other for the back end (Node js)
Everything works fine regarding Authentication where I can register a user or login with a valid password and email and bring the token and everything is fine. But the problem is that when I log in.. and bring a correct token, it works and actually logs in.
This app supposedly goes to the Profile screen after logging in.
But after The successful login, it goes to the Profile screen, and here the problem appears, which is that the token gets Revoked and does not show any data for the user, and I cannot bring his data such as his name or his data to display on his personal page.
I would appreciate someone helping me here.
I think you use JWT for your authentication. JWT contains accessToken and refreshToken. both of this tokens have expired time and refreshToken has longer expire time. whenever accessToken expired, it would be usually received error code 401. By getting this error, you need to send your accessToken and your refreshToken to the refreshToken api and get the new accessToken and RefreshToken and carry on with your new accessToken

Why do I get "Token is not revocable." from Google Auth API on online access token revocation

When trying to revoke "online" access type access token from Google's https://accounts.google.com/o/oauth2/v2/auth endpoint I get different responses, from two separate users:
a. one user, when calling GET https://accounts.google.com/o/oauth2/revoke?token=ONLINE_ACCESS_TOKEN, gets a 200 status code response;
b. another user, when calling the same endpoint, from the same Chrome extension, gets a 400 status code response, with the payload:
{
error: "invalid_request",
error_description: "Token is not revocable."
}
I've tested both tokens by calling https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=ONLINE_ACCESS_TOKEN, and both are of the same type(online) and still valid(not expired).
What could cause this issue/error message on one side, and not on the other?

Docusign API's failing after an hour

I have a docusign-sandbox account. I am trying to integrate docusign with my application and am using JWT Grant for authentication in java. I got a sample code from https://github.com/docusign/eg-01-java-jwt and it works perfectly for an hour and then the API starts failing.
Any idea how I can tackle this issue?
I'm getting the below error
I already tried changing the Token expiry time from 1hr to other lesser values(5 min, 30 min). Even then the APIs start failing exactly after an hour.
https://github.com/docusign/eg-01-java-jwt
ERROR MESSAGE
{"timestamp":1560750467288,"status":500,"error":"Internal Server Error","message":"Error while requesting server, received a non successful HTTP code 401 with response Body: '{\r\n \"errorCode\": \"USER_AUTHENTICATION_FAILED\",\r\n \"message\": \"One or both of Username and Password are invalid. Invalid access token\"\r\n}'","path":"{path}"}
Found a way around the problem.
The access token was being generated but for some reason it was not updating the token in the ApiClient Object and was using the old token only.
So now I am just creating a new ApiClient Object every time the token expires instead of replacing the old token with the new one.
The jwt grant returns an access token that is only valid for 1 hour. After that, you need to generate a new token for another hour.
Call the example's checkToken method before each API call. It should create a new access token as needed.
Added
You'll need to debug to see what's happening. Is the checkToken method obtaining a new access token after 50 minutes (it should be using a 10 minute buffer time). Is the new access token being used?

Azure Error: Client side authentication flow with Google is not supported

I suddenly started to receive the following error in my app. I'm sure it has been running fine before - atleast on my machine :-)
Error: Client side authentication flow with Google is not supported.
I get this error when I try to login using a accesstoken I've received from a gapi authorize call:
// login with google using gapi
gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: noPopup },
function (authResult) {
// Pass the accesstoken into azure
client.login("google", {"access_token": authResult.access_token}).then(
function(user) {
// logged into azure...
Then I receive the error about not supported flow.
(if I change from "google" to "facebook", the error is: Error: The Facebook Graph API access token authorization request failed with HTTP status code 400 - which makes sence since it's a google accesstoken I'm passing in)
If I paste in the url directly in a browser https://kjokken.azure-mobile.net/login/google, then everything seems to be ok.
Any ideas why this is happening?
Thanks for any help
Larsi
Thank you for using Mobile Services and taking the time to report this. We actively working on adding support for this particular scenario over the next couple of weeks, which explains what you are seeing. I will update this post when we have more information.
In the interim, did you consider using MobileServiceClient.login(MobileServiceAuthenticationProvider provider, UserAuthenticationCallback callback)?
Thanks,
-Yavor

Resources