botframework on teams channel 1:1 Authentication AAD integrated - c#

I'm looking to connect my bot on teams channel but i didn't know the way to secure this for use only in our domains (organization).
I have test to look (authentication AAD) for the Azure Web App but it's doesn't work on teams or on webchat because the endpoint adresse it's not redirected.
I have test to implement AUTH card but it doesn't work on teams.
Note : I'm using botframework C# api BotBuilder 3.15.2.2
I have look other "ask" like :
AAD authentication in Microsoft teams for Bot Framework
Is it possible to access custom tabs in 1:1 chats in MS Teams?
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/auth-flow-bot
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/auth-bot-AAD
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/authentication
https://tsmatz.wordpress.com/2016/09/06/microsoft-bot-framework-bot-with-authentication-and-signin-login/
Sincerely,
Pascal.
Edit :
I have implemented the solution sugested by Adrian, below was a piece of C# code that implement this on the MessasController.cs (Post Function):
Note ==> Adding access for localhost use
//https://stackoverflow.com/questions/51090597/botframework-on-teams-channel-11-authentication-aad-integrated
string tenantIdAAD = "";
try
{
tenantIdAAD = activity.GetChannelData<TeamsChannelData>().Tenant.Id;
}
catch (Exception exception)
{
tenantIdAAD = "";
}
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
if ([AAD_TenantID].TenantIdAAD.Equals(tenantIdAAD) || activity.ServiceUrl.StartsWith("http://localhost") )
{
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog().LogIfException());
}
else
{
await connector.Conversations.ReplyToActivityAsync(activity.CreateReply("Access Denied"));
}

The incoming message contains information that you can use to identify the user. A message looks like this:
{
...
"from": {
"id": "29:1XJKJMvc5GBtc2JwZq0oj8tHZmzrQgFmB39ATiQWA85gQtHieVkKilBZ9XHoq9j7Zaqt7CZ-NJWi7me2kHTL3Bw",
"name": "Richard Moe",
"aadObjectId": "ae361bee-9946-4082-99dc-6994b00ceebb"
},
"channelData": {
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
The channelData.tenant.id identifies the organization (O365 tenant) that the user is part of, so you can look at that and reject messages that aren't from ones that you expect.
The message also has the AAD object ID of the sender in from.aadObjectId. The auth flow in the links above is useful if you need tokens to provide to other services so you can act on behalf of the user, but if all you need is the user's tenant and identity, the message has all you need.
(Remember to authenticate the incoming request first, before trusting any information in the message.)

Related

Send notification from C# to web Cause Error Auth error from APNS or Web Push Service

I am trying to send notification to my web app using Firebase. I successfully followed the steps mentioned here to setup a JavaScript Firebase Cloud Messaging client app. Then successfully I got user approval and subscription token. Here is the code
subscribeToNotifications() {
const messaging = firebase.messaging();
messaging.requestPermission().then(function () {
console.log('have permission');
return messaging.getToken();
})
.then(function(token){
console.warn('Messaging Token: ' + token)
})
.catch(function (err) {
console.error(err);
})
}
Then I am trying to use this token to send notification from my C# console. So, here is what I did so far:
First: I generated a private key file for my service account following these steps
In the Firebase console, open Settings > Service Accounts.
Click Generate New Private Key, then confirm by clicking Generate Key.
Securely store the JSON file containing the key.
Second: I created a .net core C# console app and did the following to initialize firebase.
Installed the firebase admin package
Install-Package FirebaseAdmin -Version 1.8.0
Wrote the following code to initialize the firebase app
static void Main(string[] args)
{
FirebaseApp.Create(new AppOptions()
{
Credential =
GoogleCredential.FromFile("D:\\__\\myprojectcred.json"),
});
Console.WriteLine("Initialized");
SendMessageAsync().Wait();
}
The application successfully initialized.
However, when I tried to send the message by calling SendMessageAsync it fails in this line
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
The code is as follow:
public static async System.Threading.Tasks.Task SendMessageAsync()
{
// This registration token comes from the client FCM SDKs.
var registrationToken = "eRXeB4adi0k:APA91HGlcqh8Ow…nlrO8";
// See documentation on defining a message payload.
var message = new Message()
{
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
Token = registrationToken,
};
// Send a message to the device corresponding to the provided
// registration token.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
}
The error is
FirebaseMessagingException: Auth error from APNS or Web Push Service
Please help to figure out the problem.
Update:
The notification is sent to the server successfully when I tested it with Firefox client, so now the problem is with Edge browser only.

Send sms notify message to user when his/her account locked, how can i do that in C#

Bot Info
SDK : C#
Active Channels: SMS (Twilio)
Bot version: v4.4.3
Issue Description:
I'd like to be able to send proactive messages through SMS messages. When a user's account locked, i have that person's phone number, and i want to send a notify message like "your account is locked, please do something." Is this possible?
i checked the documentation about proactive message, which is get the "ConversationReference" through "activity", i don't know with the phone number, can i create a "ConversationReference" object, and how to tell bot about the phone number through notify controller.
Thank you.
Twilio developer evangelist here.
If you don't already have a conversation reference from a previous conversation then the documentation doesn't seem clear on how you would start a conversation. In this case, it might be easier to send the user the SMS message using the Twilio API directly.
Fortunately, unlike most channels, you can construct a conversation reference without having to have the user message the bot first since you know the user's number and you have the bot's number. Take a look at the code snippet below. You can send a proactive message to a phone number by sending a get request to http://localhost:3978/api/notify/+1##########
using Microsoft.Bot.Connector.Authentication;
[HttpGet("{number}")]
public async Task<IActionResult> Get(string number)
{
MicrosoftAppCredentials.TrustServiceUrl("https://sms.botframework.com/");
var conversationReference = new ConversationReference {
User = new ChannelAccount { Id = number },
Bot = new ChannelAccount { Id = "<BOT_NUMBER>" },
Conversation = new ConversationAccount { Id = number },
ServiceUrl = "https://sms.botframework.com/"
};
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default(CancellationToken));
// Let the caller know proactive messages have been sent
return new ContentResult()
{
Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
ContentType = "text/html",
StatusCode = (int)HttpStatusCode.OK,
};
}
private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync("proactive hello");
}
For more details on sending proactive messages, take a look at the Proactive Message sample.
Hope this helps.

Unity/Firebase How to authenticate using Google?

I'm trying to implement Firebase Authentication system in my Unity Game Project. Everything is setup properly on the console panel on the website. I've read the docs and can't find a way to login into Google using any api within Firebase within Unity. So I bought Prime31's Play GameServices Plugin for Unity.
Here are my questions:
How to authenticate using Google right within Firebase? Do I need to manage the google sign in myself?
In the Firebase docs I did find:
"After a user successfully signs in, exchange the access token for a Firebase credential, and authenticate with Firebase using the Firebase credential:"
Firebase.Auth.Credential credential = Firebase.Auth.GoogleAuthProvider.GetCredential(googleIdToken, googleAccessToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task => {
//......//
});
How can I get the googleIdToken, googleAccessToken which are being passed as parameters above?
Please help (with code). I really like Firebase and would like to make it work without any third party plugins like PRIME31.
Here is the entirety of my Google SignIn code w/ Firebase Authentication and GoogleSignIn libraries:
private void SignInWithGoogle(bool linkWithCurrentAnonUser)
{
GoogleSignIn.Configuration = new GoogleSignInConfiguration
{
RequestIdToken = true,
// Copy this value from the google-service.json file.
// oauth_client with type == 3
WebClientId = "[YOUR API CLIENT ID HERE].apps.googleusercontent.com"
};
Task<GoogleSignInUser> signIn = GoogleSignIn.DefaultInstance.SignIn();
TaskCompletionSource<FirebaseUser> signInCompleted = new TaskCompletionSource<FirebaseUser>();
signIn.ContinueWith(task =>
{
if (task.IsCanceled)
{
signInCompleted.SetCanceled();
}
else if (task.IsFaulted)
{
signInCompleted.SetException(task.Exception);
}
else
{
Credential credential = Firebase.Auth.GoogleAuthProvider.GetCredential(((Task<GoogleSignInUser>)task).Result.IdToken, null);
if (linkWithCurrentAnonUser)
{
mAuth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(HandleLoginResult);
}
else
{
SignInWithCredential(credential);
}
}
});
}
The parameter is for signing in with intentions of linking the new google account with an anonymous user that is currently logged on. You can ignore those parts of the method if desired. Also note all of this is called after proper initialization of the Firebase Auth libraries.
I used the following libraries for GoogleSignIn: https://github.com/googlesamples/google-signin-unity
The readme page from that link will take you through step-by-step instructions for getting this setup for your environment. After following those and using the code above, I have this working on both android and iOS.
Here is the SignInWithCredential method used in the code above:
private void SignInWithCredential(Credential credential)
{
if (mAuth != null)
{
mAuth.SignInWithCredentialAsync(credential).ContinueWith(HandleLoginResult);
}
}
mAuth is a reference to FirebaseAuth:
mAuth = Firebase.Auth.FirebaseAuth.DefaultInstance;
The simple answer is that there's no way in the Firebase SDK plugin for Unity to do the entirety of Google's authentication in a Unity app. I would recommend following the instructions for email/password sign on to start out.
https://firebase.google.com/docs/auth/unity/start
If you really want Google sign on (which you probably do for a shipping title), this sample should walk you through it: https://github.com/googlesamples/google-signin-unity
The key is to get the id token from Google (which is a separate step from the Firebase plugin), then pass that in.
I hope that helps (even if it wasn't timely)!
For someone asking for HandleLoginResult from #Mathew Coats, here is the function used to handle after.
private void HandleLoginResult(Task<FirebaseUser> task)
{
if (task.IsCanceled)
{
UnityEngine.Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
UnityEngine.Debug.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception.InnerException.Message);
return;
}
else
{
FirebaseUser newUser = task.Result;
UnityEngine.Debug.Log($"User signed in successfully: {newUser.DisplayName} ({newUser.UserId})");
}
}
As first, you need use Google Sign in Unity plugin to login with Google, and then, when you logged, get token and continues with Firebase Auth. Also you can try this asset http://u3d.as/JR6
Here is the code to get access token from firebase after authentication is done
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getToken(true)
.addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
#Override
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (dialog != null) {
dialog.dismiss();
}
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
Log.i(getClass().getName(), "got access token :" + idToken);
} else {
// show logs
}
}
});

Bot Framework Channel Emulator has invalid channel ID?

I'm using the C# Bot Framework library to retrieve some data from the Bot State Service. Whenever channelId == "emulator" in the code below, it fails with a 400 Bad Request. It looks like both Emulator versions 3.0.0.59 and 3.5.27 use this channel ID. Here's the returned payload:
{
"error": {
"code": "BadArgument",
"message": "Invalid channel ID"
}
}
Note that if I change channelId to something else like "skype", it works as expected.
var credentials = new MicrosoftAppCredentials(id, password);
this.botState = new BotState(new StateClient(credentials));
var channelId = activity.ChannelId;
await botState.GetUserDataAsync(channelId, activity.From.Id);
Received this answer from the Bot Framework team:
For emulator they need to use the activity’s serviceurl when create the state client. Builder automatically does that in the connector client factory:
https://github.com/Microsoft/BotBuilder/blob/master/CSharp/Library/Microsoft.Bot.Builder/ConnectorEx/IConnectorClientFactory.cs#L86
if (IsEmulator(this.address))
{
// for emulator we should use serviceUri of the emulator for storage
return new StateClient(this.serviceUri, this.credentials);
}
That error is from state.botframework.com (which is the default endpoint for stateclient) since emulator is not a valid channelid for the state service.

Authenticate using openID without login through provider

I create web application to connect to MySpace Offsite App and I want to authenticate I used the following code
var openid = new OpenIdRelyingParty();
IAuthenticationRequest request = openid.CreateRequest("http://www.myspace.com/thabet084");
request.AddExtension(new OAuthRequest("ConsumerKey"));
request.RedirectToProvider();
var response = openid.GetResponse();
OAuthResponse oauthExtension = new OAuthResponse();
if (response != null)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
oauthExtension = response.GetExtension<OAuthResponse>();
var user_authorized_request_token = oauthExtension.RequestToken;
break;
}
}
OffsiteContext context = new OffsiteContext("ConsumerKey", "ConsumerSecret");
var accessToken = (AccessToken)context.GetAccessToken(oauthExtension.RequestToken, "", "");
and I used the following refrences DotNetOpenAuth.dll and MySpaceID.SDK.dll
My problems are:
I always found that responce=null
I don't need user to login through provider MySpace so i need to remove RedirectToProvider();
My application in brief is to send status from mywebsite to MySpace account Just click on button to send
All ideas are welcome
BR,
Mohammed Thabet Zaky
If you don't want to authenticate the user then OpenID isn't what you want at all. In fact, OAuth probably isn't either. If you just want to send the user to MySpace to confirm a status message, you can very likely do that with just a crafted URL the way Twitter does -- no special protocol or library required at all.

Categories