ADAL acquire token with username and password - xamarin

I am trying to acquire token from azure AD from Xamarin Form application. I am using ADAL 4+ and I don't want user to login every time when app is launch.
Is there anyway to refresh or acquire token programmatically when application relaunch after user already successfully login.
Due to ADAL no longer have userPasswordCredientian(). I couldn't find any alternative solutions for this.

Once ADAL.NET has acquired a token for a user, it caches it, along with a refresh token. Then next time the application wants a token, it should first call AcquireTokenSilentAsync to verify if an acceptable token is in the cache. If there is a token but it has expired, AcquireTokenSilentAsync will use the cached refresh token in order to refresh the access token and if no token is in the cache, then an interactive call might be necessary to have the user sign-in again.
Here's some more information on how this works in ADAL
This is the recommended call pattern, do an AT silent call first, and catch the AdalSilentTokenAcquisitionException (because a token was not found), then do an AT interactive call.
AuthenticationContext ac = new AuthenticationContext(authority);
AuthenticationResult result=null;
try
{
result = await ac.AcquireTokenSilentAsync(resource, clientId);
}
catch (AdalException adalException)
{
if (adalException.ErrorCode == AdalError.FailedToAcquireTokenSilently
|| adalException.ErrorCode == AdalError.InteractionRequired)
{
result = await ac.AcquireTokenAsync(resource, clientId, redirectUri,
new PlatformParameters(PromptBehavior.Auto));
}
}
I would recommended moving to MSAL...here's documentation on the differences between ADAL and MSAL and specifics on the username/password flow in MSAL and how to migrate from ADAL.NET 4.x to MSAL.NET 2.x and the just released MSAL v3 api.

Related

Blacklist for external token ASP.NET

Currently, I'm developing an app service using Microsoft M365 authentication. The problem comes when the user has already logged out, but the token provided by Microsoft is still valid, and can still be used to access my backend API. I've tried to revoke it using Microsoft graph
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
await graphClient.Me
.InvalidateAllRefreshTokens()
.Request()
.PostAsync();
But another problem is that all my sessions are revoked too, so is there any way to implement a blacklist to store the token? I can only use MSSQL Server to store data.

What URL do I use to send users to google oauth2 consent screen

I am trying to write a simple application to access google's api using user authentication tokens and html requests, however I am struggling to find what URL I send users too in order for them to select a profile and sign in.
URL I send users too in order for them to select a profile and sign in.
The thing is you are confusing authorization and authentication. Oauth2 a user can authorize you to access their data, it has nothing to do with logging in to your application that's OpenID connect.
However what you are probably looking for is the oauth2 consent screen This is the screen where the user consents to your application accessing their data.
https://accounts.google.com/o/oauth2/auth?client_id={clientid}&redirect_uri={redirectURI}&scope={scope}&response_type=code
Remember this is only the first step if they consent then you will be given an authorization code your application must then exchange the authorization code for an access token which you can use to access the api.
You may find this video helpful in understanding the fill Oauth2 dance. Understanding Google OAuth 2.0 with curl
If you are looking to login a user and check their profile something like this would be better
[GoogleScopedAuthorize(PeopleServiceService.ScopeConstants.UserinfoProfile)]
public async Task UserProfile([FromServices] IGoogleAuthProvider auth)
{
var cred = await auth.GetCredentialAsync();
var service = new PeopleServiceService(new BaseClientService.Initializer()
{
HttpClientInitializer = cred
});
var request = service.People.Get("people/me");
request.PersonFields = "names";
var person = await request.ExecuteAsync();
return View(person);
}
The full tutorial and companion video can be found here Asp .net core 3 and Google login

Google API Refresh Token and Access Token Questions (Java BE + Web App)

I want to do something very similar to this tutorial, in which I'm getting the authCode from web client and sending that authCode to a Java BE app to get credentials of an user and then, using the credential to gain access to google sheet api to create a spreadsheet on user's drive.
According to google-api-java-client/oauth2 doc:
GoogleCredential takes care of automatically "refreshing" the token,
which simply means getting a new access token.
Would I still be able to take advantage of the above statement, in which GoogleCredential automatically refreshes the token if I'm authenticating and asking for permission on the client web app - aka, I call the grant offline request on web app and then, getting the actual GoogleCredential in a Java BE app (using the authCode)? If so, how does that work? Why would others suggest to store the refreshToken in a db?
If I do decide to store in a db, would storing the refreshToken with the key as my app's unique identifier for a user be OK (instead of using the suggested sub identifier)? Is there a limit on the amount of time I can call the token to get a new accessToken per user? Even if an accessToken hasn't expired, is it better to just get a new accessToken for every new request (seems more secure)?

Firebase 3.x - Token / Session Expiration

Does anyone know how long would it take for the token to expire? There no option now to set the token validity on the console.
Since May 2016 Firebase Authentication login sessions don't expire anymore. Instead they use a combination of long-lived account tokens and short-lived, auto-refreshed access/ID tokens to get the best of both worlds.
If you want to end a user's session, you can call signOut().
Its does expire. After one hour logged in the token id expire. If you try to verify sdk returns a error "Error: Firebase ID token has expired. Get a fresh token from your client app and try again. See https://firebase.google.com/docs/auth/server/verify-id-tokens for details on how to retrieve an ID token."
Is There such a way to change expiration time to Firebase token, not custom token.
Anybody that know how this really works.
For anyone that is still confused, it is all explained in great detail here
If your app includes a custom backend server, ID tokens can and should
be used to communicate securely with it. Instead of sending requests
with a user’s raw uid which can be easily spoofed by a malicious
client, send the user's ID token which can be verified via a Firebase
Admin SDK (or even a third-party JWT library if Firebase does not have
an Admin SDK in your language of choice). To facilitate this, the
modern client SDKs provide convenient methods for retrieving ID tokens
for the currently logged-in user. The Admin SDK ensures the ID token
is valid and returns the decoded token, which includes the uid of the
user it belongs to as well as any custom claims added to it.
If the above answer is still confusing to you,
This is what i did:
firebase.auth().onAuthStateChanged(async user => {
if (user) {
const lastSignInTime = new Date(user.metadata.lastSignInTime);
const lastSignInTimeTimeStamp = Math.round(lastSignInTime.getTime() / 1000);
const yesterdayTimeStamp = Math.round(new Date().getTime() / 1000) - (24 * 3600);
if(lastSignInTimeTimeStamp < yesterdayTimeStamp){
await firebase.auth().signOut()
this.setState({
loggedIn: false
});
return false;
}
this.setState({
loggedIn: true,
user
});
}
})

How to reset google oauth 2.0 authorization?

I'm using Google APIs Client Library for JavaScript (Beta) to authorize user google account on web application (for youtube manipulations). Everything works fine, but i have no idea how to "logout" user from my application, i.e. reset access tokens.
For example, following code checks user authorization and if not, shows popup window for user to log into account and permit web-application access to user data:
gapi.auth.authorize({client_id: CLIENT_ID, scope: SCOPES, immediate: false}, handleAuth);
But client library doesn't have methods to reset authorization.
There is workaround to redirect user to "accounts.google.com/logout", but this
approach is not that i need: thus we logging user off from google account not only from my application, but also anywhere.
Google faq and client library description neither helpful.
Try revoking an access token, that should revoke the actual grant so auto-approvals will stop working. I assume this will solve your issue.
https://developers.google.com/accounts/docs/OAuth2WebServer#tokenrevoke
Its very simple. Just revoke the access.
void RevokeAcess()
{
try{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/revoke?token="+ACCESS_TOKEN);
org.apache.http.HttpResponse response = client.execute(post);
}
catch(IOException e)
{
}
}
But it should be in asyncTask
It depends what you mean by resetting authorization. I could think of a three ways of doing this:
Remove authorization on the server
Go to myaccount.google.com/permissions, find your app and remove it. The next time you try to sign in you have to complete full authorization flow with account chooser and consent screen.
Sign out on the client
gapi.auth2.getAuthInstance().signOut();
In this way Google authorization server still remembers your app and the authorization token remains in browser storage.
Sign out and disconnect
gapi.auth2.getAuthInstance().signOut();
gapi.auth2.getAuthInstance().disconnect();
This is equivalent to (1) but on the client.
Simply use: gapi.auth.setToken(null);
Solution for dotnet, call below API and pass the access token, doc - https://developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke
string url = "https://accounts.google.com/o/oauth2/revoke?token=" + profileToken.ProfileAccessToken;
RestClient client = new RestClient(url);
var req = new RestRequest(Method.POST);
IRestResponse resp = client.Execute(req);

Resources