Authorization flow for Microsoft Graph API - azure-active-directory

Very new to the Microsoft ecosystem, trying to understand the flow.
Use-case: we need a Teams bot that sends personal messages to users saying "A customer is waiting at location X" with 2 buttons [Accept] and [Reject] containing personalized links like "https://someurl.com/accept?message=123&user=[user_id]".
How I think I should do it:
Add a special user "servicenotifications#ourdomain.onmicrosoft.com"
Authorize the user & then get a token
Use the token in Send message with cards with cards containing button links
My problem: Got confused with authorizing my special user. Examples on auth V2 require to "redirect the user to the Microsoft identity platform /authorize endpoint." — in a nutshell, show them the login screen, ask for consent and so on.
But my user is a special notification bot, there is no human and I need that fully automated without any user interaction at any point. It's basically a background service sending messages under specific circumstances. Like a Slack bot telling you "Hey, reminder, John has birthday tomorrow".
My questions:
In general, am I moving in the right direction? Or is there a better way for the usecase?
How do I authorize this user without showing any login screen? Because that's an app, a bot, it's not a human and will be controlled fully externally.

Since authentication will be initiated by a bot, the ideal solution is to implement the OAuth2 Client Credentials Flow so that a service principal can be authenticated and authorized. Take a look at Get access without a user for more information.
There may be some operations that may not be allowed for service principals (documented as applications) like Sending chat message to a chat.

Related

Sitecore - How to get User ID if the user was logged in using external identity provider (Salesforce SSO)

I have a little bit of problem with the authentication on Sitecore website. Basically there is a button on the navbar, and when user clicks on the button, it redirects the same user to Salesforce to log in (Implementation of SSO). Basically I am using Salesforce as a identity provider and Sitecore Website as a service provider. Now I have a question? When user is logged, how can I get the ID of that user.
Do users in Sitecore User Manager have the same ID as the users in Salesforce, or I can just get a email to identify the user?
P.S: Sorry if this is a really stupid question, but I am a begineer when it comes to making Sitecore websites and the SAML SSO. Thank you in advance
Stop with the Sitecore and Salesforce for a second, you'll need to cover some basics and click through the login process manually before you automate it.
You probably are using a "connected app" in Salesforce that includes OAuth2 config (consumer key also known as client id; a secret; a list of scopes telling what this app is allowed to do on behalf of this SF user; a list of allowed urls that can login using this consumer key and secret. Etc.) It might even have something about Canvas Apps at bottom of the page.
Next would be - who's logging in. A core Salesforce user or do you have Partner Community, Customer Community (recently rebranded to "Digital Experiences").
Open incognito window and go to https://openidconnect.herokuapp.com/
For login host leave as is if you have production user or test.salesforce.com if you go from sandbox (you can also use branded urls, mycompany--dev.my.salesforce.com etc). If you have a community user you'll have to change the url to whatever is the community base url, like https://dev-mycompany.cs123.force.com/mycommunity
Don't change anything else, click next, next, next. This will take you through OAuth2 "web server flow" (one of many ways to log in). You type the username/password to SF screen and go back to that herokuapp with "authorisation code". The app has few minutes to swap that code for actual final "access token" and couple other pieces of info. Final step in this wizard calls OpenId "userinfo" - returning some info about the user that logged in. That's where you could pull the email if needed (and if there are extra fields you'd like SF to return in this process that's configurable too)
Close that browser window. Check the "connected app" in SF. Open new incognito window, do same thing but this time put your url, consumer key and secret (you might have to edit the app in SF first to allow callbacks to https://openidconnect.herokuapp.com/callback).
So now you should have rough idea about whole login process. Your sitecore app probably does same thing, receives authorisation code and exchanges it for final token. At that point you have valid SF session ID you could use to call that "userinfo", run queries (if the app allowes API access, check the "scopes") etc.
I doubt the Sitecore developer created it all by hand, you probably have some Spring stuff like spring.security.oauth2.client... My Java days are long gone but if you get better at manual click-click-click through the flow you should be able to follow existing code?
It's a big topic and there are other ways to do it (other OAuth flows, sending info about the current user when you have external page embedded in SF as iframe, you'd need to read about "canvas apps")... but that's best guess based on info you provided. You might want to check some trailhead courses too like https://trailhead.salesforce.com/content/learn/projects/build-a-connected-app-for-api-integration/implement-the-oauth-20-web-server-authentication-flow
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm
https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/code_sample_auth_oauth.htm (Java but very hand-crafted raw HTTP, probably that Spring security is better)

Salesforce Server-to-Server integration without any user involved

I am working on a integration with Salesforce using REST APIs and, as part of the project, I need to send updates to Salesforce and these updates are not user triggered, they are system triggered.
Because of that, what I expect to see on Salesforce Field History is not a user name but the name of our Connected App (the app that made the update).
What I see today is the user name because the way the integration was made initially using OAuth Authorization Code flow.
To change that part of the project, I followed the link (OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration): https://help.salesforce.com/articleView?id=sf.remoteaccess_oauth_flows.htm&type=5
Making that, I was expeting to generate a token for a System, not for a User, but that's not what happened: when I used the token generate from the JWT Bearer Flow and ran the update, the Field History still shows the user name.
What could I do then?
Which are the options in Salesforce to achieve the behavior I'm expecting?
The most important, in my opinion, is to have a Token for our system, not for a user.
Thanks!
Everybody is an user in Salesforce. Even if you access unauthenticated pages (some contact us form? case or lead capture) - it gets tracked under special Guest User.
It sounds stupid but gives you unified interface to control permissions (Profiles/Permission sets). You want guests to access only FAQ articles and make cases? Sure thing, do it in profile, don't get paranoid about people trying to guess right URLs. You think an app was hacked? You can terminate the session just like any other "user". Want to allow login only in certain hours and from certain IP? Sure.
An app connecting with JWT will still need username (main difference being it's "just" certificate for signing the request instead of password).
Your best bet is to create dedicated "Mr System", "SystemX integration" account. It sounds like waste of license but in the long run saves you questions "why did you edit my account at 1 am" and you could even use it as backup account if you use SSO and it ever fails...

Signup for email accounts from GAE app

I am faced with a rather strange request and there isn't much material online tackling that.
I am building a web app on GAE ... front end, back end, datastore, blob store, user accounts, the whole nine yards ...
Part of the requirements is to have a user communication system, (users sending messages to each other, just like Facebook) as user emails are not to be shared among other users, and the web app shall only send emails to the user sign up email strictly for security and administration purposes, and wont flood their inbox with notifications like some websites do.
I have narrowed narrowed it down to 4 options
Option 1:
Reinvent the wheel - Build this whole system form scratch on the Datastore and Blob store. However, not only is it expensive, but also I am not gonna go through all of that (just saying honestly)
Option 2:
Build a bouncing system ... User A sends message to app ... app bounces email to User B. Not very Elegant, impossible to create threads and conversations, eats up app Mail Quota used for Marketing and what not.
Option 3:
Host My own Email server onsite. Patch an API servlet and run the whole show through API. Very valid, except that the client doesn't want anything on site, and I wont be around to maintain it for him.
Option 4:(Best option if someone helps out)
Implement option 3 on a 3rd party email provider. Which brings us to the question, is there any respectable email provider that allows account sign up through API ?? I need to create a shadow email account on a 3rd party server(that the user will never know it exists) every time someone makes an account on my app. Then store all emails and their generated passwords in the Datastore, and when user logs in my web app, web app logs in 3rd party server, retrieves messages and serves it. When he wants to send a message, web app gets the message, sends an email using API as well. If someone knows how to do that on Gmail, I would be eternally grateful (but I highly doubt google allows that)
Note
I can implement the whole setup on xmpp/Jabber servers as well but these free servers keep changing all the time and they change their configurations ... bottom line they are not very reliable.
Thanks a lot guys !! I really appreciate any feed back and if you have any other suggestions please don't hesitate !! This is by no means a solid plan yet.

Facebook app notifications: can they be via email and push for mobile/tablet?

I'm trying to find information on developing the UX of Facebook notifications being sent from a FB app.
The app will require FB permissions for users to save favorite content within the app (iFrame). We want to remind users to return to the app (once a month) when the public content is updated, but we also want to remind them to return (once a month) when the authorized content is updated.
Is it possible to send email and push notifications for mobile/tablet in these scenarios? Or is it best to only send onsite notifications? Are email/push notifications even possible? I am having a hard time finding information that is clear on the FB Dev. site. Thanks!
All apps developed using developer API can enable notifications. That's why games can send you notifications using your original notification stream.
I would also advise you to only use this communication model, since e-mail from a Facebook app might not be the way Facebook users want their notifications. Also remember that you have to ask for permission to send the user e-mail, and gives the user another argument not to use your FB-app. The less permission you ask for, the more easy it is for users to accept you apps permission request.
Further more, Facebook users can turn off e-mail permission at any given time. Then you would not be able to send e-mails and lose your way of communication to your users.

How does the app know whether it's ok to send XMPP messages to the user in App Engine?

I've read this paragraph from the App Engine documentation a dozen times and still am completely in the dark about how chat invitations work:
Invitations
Google Talk and other chat servers
will only accept messages for users
that are "subscribed" to the sender,
either because the user invited the
sender to chat or because the user
accepted an invitation to chat sent by
the sender. An App Engine app can send
chat invitations using the service
API. As with sending email, a best
practice is to send a chat invitation
only when the user asks, such as by
clicking a button on a web page.
Alternatively, the app can ask the
user to send an invitation to the
app's XMPP address to enable receiving
of messages.
App Engine accepts all chat
invitations automatically, and does
not communicate invitations to the
application. App Engine will route all
chat messages to the application,
regardless of whether the sender
previously sent an invitation to the
app.
Maybe the problem is I haven't used chat so I'm not familiar with how invitations work in practice. But the first issue is how/why/whether an application needs/gets permission to chat with a user.
The paragraph above seems to say the following:
The application needs permission to send XMPP messages to the user (and the user needs permission to send XMPP messages to the app?), so
The user has to send an invitation to the app to allow it to send messages to the user (and the app has to send an invitation to the user to allow the user to send messages to the app?)
App Engine receives the chat invitation but does not communicate it to the app
Question: How does the app know whether it's ok to send messages to the user since App Engine does communicate anything to app about the user's response to the invitation?
Gmail is a great example:
I send a message to my friend who is not on my "Friend List". Gmail does not deliver my message, but instead delivers a message that says "Anthony would like to chat. Do you accept?"
If my friend clicks "yes", they get my message and I'm on their friend list and they are on my friend list, and we can chat freely without Gmail making sure it's okay.
If my friend clicks "no", they never see my original message and GMail asks permission if I try again later.
So the App does communicate with the user on the other end, it just doesn't relay the message, only that I'm interested in being chat-buddies.
quick update
Another way of looking at this (if you remember these days), is a collect call. The operator simply says "Do you wish to accept a collect call from Jones?" The operator doesn't say "He says it's really important, he's in jail." And the operator doesn't say "He said no, you can rot in jail." to Jones. They broker the connection without either party making real contact until both parties agree.
(Of course, we would always say our name was "I'm stuck at the mall!" when we tried calling home collect. But since there is no charge for a chat, such sneaky workarounds are not necessary in the XMPP world.)
Use the get_presence() function to determine if it's ok to send to the user. If you send a message to a user that has not accepted an invitation, most XMPP servers (including Google Talk) will not deliver either the message or an automatic invitation. With Google Talk at least, a user who has accepted an invitation will be "present" even when they're logged off, since Gmail can deliver your XMPP messages as pseudo-emails.

Resources