Get accesstoken from Microsoft Authentication Library (MSAL) for .NET without Login into the Web Server - msal

i am building a saas website(aspnetcore webapi 2.1+angular js) which allow user to connect thier email account(Gmail,outlook mail..),so they can receive and send email without switching out. i have completed the gmail part smoothly, but when i come to outlook mail, i stucked on the authentication part. what i wan't (and i have already done on Gmail intergration) are :
direct user to the Login page with necessary parameters(tenantid,clientid..)(https://login.microsoftonline.com/common/oauth2/v2.0/authorize.....)
when user is logined in, store the tokens in database, and manage them(get new refreshtoken and accesstoken after expired automatically).
i have read a lot articles on msdn,github,stackoverflow, and found the nearest solution is this one:
https://github.com/jasonjoh/dotnet-tutorial, but it logins the ms user to the my website. i just wan't to popup/redirect the user to microsoft login page, and get the user's accesstoken to get/send thire emails through Microsoft Graphy Api, not login as a microsoft account. i can't found similar code to Google API in MSAL
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
tokenId,
CancellationToken.None,
// new FileDataStore(credPath, true)
(IDataStore)userApiTokenRepository //<------------token management
, new LocalServerCodeReceiver(
#"<html>
<head>
<script>
window.onload(function(){window.setTimeout(3000,function(){window.close();}});
</script>
</head><body>Successfully linked with gmail!</body></html>")
).Result;```
the code above will direct to google login page(even it is called via http post from js client), and store them in my customer repository. do i miss something in the MSAL, or i must implent the 0auth flow manually?

To get an access token for MS Graph the user has to sign-in first so you can send their credentials to acquire the token. You cannot bypass the 1st sign-in page.
MSAL can do this for you, by interception the openIdConnect event OnAuthorizationCodeReceived and then calling AcquireTokenByAuthorizationCode with the code received. I would recommend you to take a look at this sample, set a breakpoint on OnAuthorizationCodeReceived and analyze the flow that is happening there.
About implementing the flow manually, it will be a hard task to deal with the token expiration and the security points. I would highly recommend to use MSAL.

Related

Sending automated emails using Gmail API with Java and Oauth authentication

I have a web app which sends emails (gmail) in name of my users
When a user registers, she supplies gmail account and password. Also she has to enable access for Less Secure Apps (I recommend to create a new account for this)
Then I can open a gmail session
session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user.getEmail(), user.getPassword());
}
});
and send emails on her behalf.
Unfortunately this is going to stop working next 30th May, when Google will allow only OAUTH2 access
I have followed Java Quickstart for Gmail API and I have code up and running for sending emails with OAUTH2: enable gmail api, create an application on google cloud platform, grant send permission, oauth2 client id credential created...
The problem I have is I can't see a way to automatize this task because when creating an authorized credential, a consent screen displays on browser and you have to select the account to be granted manually (maybe because my app in google cloud platform is still pending to be reviewed)
Is there a way to infer the gmail account you want to access from the credentials file (client_secret.json)? Is there a way to automatize this?
No, or yes. It depends.
The whole point of OAuth2 is to improve security by working with authorization tokens rather than asking for user credentials. To do this the user has to consent to the app's access request, and thus the OAuth consent screen cannot be bypassed. This is
explained in Google's documentation. It's not related to your app's review status but rather it's the way OAuth works.
You can still work in a similar way, though . Instead of asking for username and password upon the user's registration you can redirect them to the OAuth consent screen so they can authorize your app. Make sure that your app is requesting offline access type and then you can retrieve an access_token and a refresh_token. These will essentially work as your credentials and you can use the refresh token to generate new access tokens when needed without having the user go through the consent screen each time.
The refresh token doesn't have a "natural" expiration so you can keep using it indefinitely, but there are a few scenarios where it will become invalid, such as it not being used for six months, the user changing passwords (if using Gmail scopes), the user manually revoking access, etc. In these cases you will need to direct them to the consent screen again to reauthorize your app.
In this sense, your app can still work automatically without user input except the initial setup, which you already had to deal with when they supplied you with their credentials. The refresh token expiration can even be compared to what you had to do when the users changed their passwords in your current workflow.
One exception to this are service accounts. If you and your users are part of a Google Workspace domain you can delegate domain-wide access to it, then the service account will be able to access user data without any manual input. Of course, this is because as the domain administrator you pretty much own all the accounts under it. But if you're working with a publicly available application you will have to deal with the limitations I mentioned above.
Sources:
Google's auth overview
Using OAuth 2.0 to access Google APIs
OAuth 2.0 for web applications
The OAuth consent screen

Chat bot single sign on

I have a bot running on a hosting page where users are logged in using SSO.
I want to authenticate the user in the bot automatically when the bot starts and I do not want to use anAuthCard to do it. Just want to automatically authenticate the user without prompting anything to him, just using SSO.
I found an article that refers three ways to authenticate an user in the bot:
Sharing the client's user token directly with the bot via ChannelData
Using an OAuthCard to drive a sign-in experience to any OAuth provider
A third option, called Single Sign-On (SSO), that is in development.
And, according to the article my situation is:
WebChat in an authenticated website where the user is already signed in and the website has a token to the same identity provider but to a different app that the bot needs -> in the future, this is single sign-on, but for now you 'll need to use an OAuthCard.
Is there any update about this functionality? How can I authenticate the user into the bot without using an OAuthCard or a SigninCard?
Thanks in advance
Not sure if you have tried the option of using WebChat with Azure Bot Service’s Authentication which provides built-in authentication capability to authenticate chat users with various identity providers such AAD, GitHub, Facebook, etc.
If you are looking for this built-in feature, then probably you need to build your own custom built solution using Google sign-in by passing the token ID of the authenticated users. Or for an Account linking OAuth2 solution as explained in this link: How to implement Login in Dialogflow chatbot.
Microsoft guys Are looking at the issue now. you can track the progress here.
I implemented a solution that worked for me. I have the bot running in a .net core web app
Here's what I did:
Generate an userId before initializing the BotApp
When the user clicks on the button to open the webchat, I'm opening an authenticated controller in a popup that receives the generated userId. The page is authenticated, so you will need to authenticate. I store the userId in my DB, along with access_token and some user information. The controller should be created in the same webapp where the bot is running.
After storing all the information I close the tab and start the BotApp with the generated userId
In bot code you will be able to query your DB (using userId).
To wait until the popup close, you can have a look into this here.
I hope that this helps someone.
Best regards

Google API sends account email alert

I'm developing an application that utilizes Google sign-in and the Gmail API. My test users, once logged in, keep receiving an email like the attached file.
Other applications with similar functionality (basic email access) do not seem to trigger these emails. Any ideas? It makes my app seem less trustworthy.
One possibility is that you are obtaining tokens with offline=true indicating a requirement to use the refresh token to renew expired access tokens. If you only require short-term access, perhaps you should remove the offline parameter in the construction of your auth request link.
In this scenario once the access token expires, then the scope will no longer be usable or renewable and so your end-users should not receive the alert emails.

actions-on-google implicit flow and access_token change?

I have developed a Google Action for Assistant (with Api.ai). I have to use a Sign-in method because my app use a website where the user have to sign-in and make something.
In the action console I setup account linking with IMPLICIT method and under AUTHORIZATION URL I inserted my url for the login. It's works.
When I speak for the first time (for testing) to my Google Home, on my smartphone appears the notification for account linking... perfect. My website create a token and record it and every time after my webhook will call with the same access_token. Perfect.
Two questions
This access_token is linked to my google-account forever or google may change it?
How can I disable this account-linking and reset my google-action? I want to re-link my assistant with new access_token. I try to return a http 401 from my webhook but it's not work.
The access token is just a piece of string so Google cannot change that exact one. It might have a lifetime.
I am pretty sure Google has an endpoint that revokes the access token.

Access email from Gmail from server

I am trying to be able to set up a cron job to read contents from a certain email in my gmail inbox daily. I lookeed up gmail api documentation and noticed that the only way to authenticate my requests to access email data is via OAuth 2.0 which requires user authorization. Is there a way to authorize my app to access emails from a particular email id without the need for the user to manually take any actions.
I found this: https://developers.google.com/identity/sign-in/web/server-side-flow. I was wondering if there is any way to follow this workflow without having to build the UI?
Technically speaking you can use Oauth2 you just have to have the user authentication your application once. You will get a refresh token then you can use the refresh token to get a new access token from cron. Unless this is a Google domain account you cant use service accounts. There is no way to pre authorize a service account to access a normal user gmail.
Alternative: have you considered going directly though the mail server? Skip the rest api. https://developers.google.com/gmail/oauth_overview Note: That page also speaks of XOauth2 I haven't tried it yet you can still access SMTP and IMAP using username and password.

Resources