Send mail on_behalf_of with a guest user account - microsoft-graph-api

I'm trying to let an api send a mail on behalf of a user.
I have an UWP application (Azure AD App "A") that posts some data to the API (Azure AD App "B")
The API are then going to collect some more data and send a mail as the user that posted that data.
When the post is received by the API the bearer token has "AUD" and "SCP" for the API, now I do a request to Azure AD and swaps the token for a new one with "AUD" and "SCP" for MS Graph API. This works pretty good, until there is a guest user that sends the data. Then I get an "Unauthorized" result back from Graph API.
I assume the reason is because I get the first token as the guest user and then tries to send mail with an account in another tenant.
What can I do to bypass this?

We can't send mail on_behalf_of with a guest user account because a guest user doesn't have O365 Exchange Online license in this tenant.
Although maybe the guest user has O365 Exchange Online license in its own tenant, it is not allowed to send mail from this tenant.
It is expected.
What can I do to bypass this?
If you want the guest user to send the mail from this tenant, it's impossible.
But I think sending mail from its own tenant is not what you want and it will require you to create app registration in that tenant or use multi-tenant app. You need admin permission of that tenant to do that. So it's impossible neither.

Thanks Allen!
Now when I cooled of a bit (I have extremely hot in my work area) I realized what I tried to do and why it didnt work ;)
I'm solving the problem by looking at the bearertoken and see if it is a Guest user who uses the app and send from an "no-reply" account in those cases.

Related

Bypassing using OAuth for GSuite Mails

Is there a way for me to bypass the need to use OAuth for me to send out emails using the G-Suite platform in my application
I am still able to send out using the Microsoft 365 platform but some of my clients will not move to 365 and prefer G-Suite
You can use a service account. You will need to have the admin of the domain configure domain wide delegation to an account on the domain.
Once delegation is configured you can then use your code to impersonate a user on the domain and send emails on their behalf. This is what i normally do with sa a system designed for sending email conversation mails. When a user creates a new account the system could send an email conformation email. On behalf of say noreply#yourdomain.com
Your issue is going to be with the fact that your clients are the ones who own the domain so your going to have to get the google workspace admin for your client to set this up for you.
The other option would be to use standard oauth2 and authorize a user on the domain and send emails on their behalf.
The issue with that is going to be your application will need to be verified with one of the highest protected scopes. Your app will need to go though a security audit before it is verified. Last I checked that audit will cost you $15k-75k

Azure static web app - send email from the logged in user a week later. How to handle authentication?

I have an azure static web app set up with durable functions. I want the user to log in with their microsoft account, write a message and an email address, and that email will be sent a week later using the MS Graph Api.
I don't want to use Mail.Send application permissions as this lets the app send from anyone in the organisation. So I have Mail.Send delegated permissions.
After the user logs in, how can I send mail a week later, as the access token will have expired? Do I need to handle the refresh token manually or is there a built in way Azure Static Web Apps does this?
No built in way. You will have to manually refresh the token in your backend until you need to send the email out.

How to revoke access/refresh token on microsoft graph API

I have integrated microsoft teams in my project where a user can give us access to create meetings on teams on his/her behalf. But now I want to give the user a option to disconnect his/her account i.e. we will no longer be able to create meetings on user's behalf.
I am facing few problems in this flow:
I am unable to find an API where I can send request on user's behalf
to invalidate a access/refresh token.
If I remove the token stored at my end and then user again tries to connect their Microsoft account with our website it no longer asks for user's consent(which is basic requirement for OAuth) to give access to our app(if user is logged in Microsoft account on the browser he/she do not see the consent page and account is directly connected with our website and we get the refresh/access token).
Can someone help me on this?
At the end all what I want is when user tries again to connect his/her Microsoft account with our app he/she see the consent page(every time he tries to connect account) and then user clicks the allow button which will give us access and refresh token.
If the user has granted access to the application, Azure AD will issue an access token and a refresh token for the resource.
The lifetime of the access token is usually about 1 hour. During its lifetime, even if the application is deleted, it is still available, but you will not be able to use the refresh token to obtain the access token again.
1)To invalidate access token on users behalf, Refer this DOC.
2)For fetching the access token using the refresh token please refer this DOC.
Hope this helpful.
An alternative solution for prompting the user to the consent page is just simply appending the prompt="consent" in the OAuth2 URI prameters:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id=xxx&redirect_uri=xxx&scope=xxx&state=xxx&access_type=offline&prompt=consent
_____↑↑↑↑↑↑
Here you can find the documentation about the parameters.

Allow Azure AD app to send mails on behalf of only one specific user

I'm building a daemon service (no user interaction) which needs to send a mail via MS Graph. I've registered an app in Azure AD and given it the User.Read.All and Mail.Send application permissions and given admin consent for those.
In my Java code, I'm using the ClientSecretCredentialBuilder for authentication. By doing
graphServiceClient.users("johndoe#mytenant.com").sendMail(params).buildRequest().post();
I can send an email on behalf of John Doe. However, technically, I could send an email on behalf of any user in this tenant. Is there a way to configure the app so that it can only use a specific account to send mail from?
Graph API doesn't yet support such a feature.

DocuSign - Getting a user ID for a user whose organization admins has pre-authorized the application

Any route requires you to be authenticated as a DocuSign user to use it. With the standard service integration flow, you direct the user through docusign's /oauth/auth flow, use the returned code to get an access token via /oauth/token, then use that token on /oauth/userinfo to get the user's ID which you can then sign and use in a JWT.
Instead of directing users through the oauth UI to get their consent, DocuSign allows organization admins to pre-authorize an application for everyone in the application. No need to send organization members through the oauth flow. Great.
However, once this action has been taken, it's not clear how my application could make requests on behalf of any user, since the /oauth/userinfo route that gives you the user id requires an oauth code that you get by passing the user through DocuSign's oauth browser UI.
More specifically: if the admin of foo.com's DocuSign organization authorizes my app, and bob#foo.com starts using my application, how do I get bob#foo.com's user ID to create a JWT with?
When you say "bob#foo.com starts using my application" what, exactly, does that mean?
Case 1: Bob is interacting with your application. In that case, you should be using a User Application OAuth flow such as Authorization Code Grant to enable him to login.
If your app needs to later act on behalf of Bob when he's not around, then store Bob's user id for later use with the JWT grant.
Case 2: Your app is running in the background (no human interaction). At some point your app needs to starting doing things for Bob by impersonating him. All you have is his email address.
If this time arrives and your app has had no interaction with Bob, then yes, you need prior access as an admin (in Bob's account) so you can look up Bob's user_id from his email.
This second account would be the "admin user account" for your app. The account would need admin privileges to lookup the user's information. Your app would get access to this admin account when your app is installed.
Use the Users:list API call. Remember to encode the email address.
Example:
GET call: /v2/accounts/{accountId}/users?email=larry%2Buser%40foo.com
Re: user_id lifetime I'm reasonably sure that the user_id guid doesn't change for a given accounted user (someone who is a member of an account on DocuSign). I will check to make sure.

Resources