how to implement certificate based authentication for Microsoft Bot Framework v4 bot in the code using .netcore? - azure-bot-service

I'm looking for certificate-based bot authentication. I found some approach in node js as below
const adapter = new BotFrameworkAdapter({ appId: process.env.MicrosoftAppId, useCertificateAuthentication: true, certificateThumbprint: '33***608A6******19***325D*****8****', certificatePrivateKey: certKey }); const fs = require('fs'); var certKey = fs.readFileSync('./DEV-private.key').toString() .
If you see the above piece of code there instead of app password we are using a certificate for app id authentication of the bot.
But I just want to implement the same in .netcore 3.1. I'm not able to find any reference on how to do this.

The BotFramework Adapter incorporates the Authentication library for setting up authentication via a certificate. You can see which classes and properties are used and/or available by referencing Microsoft.Bot.Connector.Authentication in the botframework-dotnet repo, in particular the AdalAuthenticator class. You can see how it is used and what properties are passed in the BotFramework Adapter.

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.

How to add permission while making a request to outlook calendar api (create event)?

I was trying to add outlook calendar api (create event) to my web app but stuck on an error of unauthorization. So I guess it might be the reason that I did not add permission?
This is my ajax function:
function addEvent(){
var newEvent = {};
newEvent.subject = document.getElementById('event-name').value;
newEvent.body = document.getElementById('event-des').value;
newEvent.start = document.getElementById('start-time').value;
newEvent.end = document.getElementById('end-time').value;
newEvent.location = document.getElementById('location').value;
console.log(JSON.stringify(newEvent));
const xhttp = new XMLHttpRequest();
xhttp.open("POST", "https://graph.microsoft.com/v1.0/me/events", true);
xhttp.setRequestHeader("Content-type","application/json");
res.setHeader('prefer', 'outlook.timezone="Pacific Standard Time"');
xhttp.send(JSON.stringify(newEvent));
}
But I got an error of unauthorized to make post request to https://graph.microsoft.com/v1.0/me/events. Can any one point out what I am missing here? I am very new to this, any help would be appreciated.
Learn how to authenticate and work with permissions to securely access data through Microsoft Graph. Explore the documentation below to learn about app registration, authentication libraries, authorization, and other parts of the Microsoft identity platform that support Microsoft Graph development in the Microsoft Graph auth overview section for more information.

Is there an issue with Bot Framework Virtual Assistant template when Direct Line App Service Extension is enabled

I have Azure Bot deployed with Virtual Assistant Template, which was working fine (And still working in Portal's Test In Web Chat feature) until I enabled Direct Line App Service Extension.
Primary objective to enable DL App Service extension is to isolate bot access and secure app service.
I have followed MS documentation https://learn.microsoft.com/en-us/azure/bot-service/bot-service-channel-directline-extension-net-bot?view=azure-bot-service-4.0 and ensured every step is configured correctly.
Primary step to make sure DL app service is working correctly is to check if https://xxx.azurewebsites.net/api/messages or https://xxx.azurewebsites.net/.bot/ url return correct json result f.x: {"v":"123","k":true,"ib":true,"ob":true,"initialized":true}
But instead i am getting Error Response 400 Bad Request and error message appeared in browser is : "Upgrade to WebSocket is required."
I couldn't even reach to a step where troubleshooting guide mentioned here : https://learn.microsoft.com/en-us/azure/bot-service/bot-service-channel-directline-extension-net-bot?view=azure-bot-service-4.0#troubleshooting could help to resolve.
As i said earlier Bot is still working and the url : https://xxx.azurewebsites.net loads site correctly , can be seen in below
Any help is appreciated
These are the changes I have done and it worked:
Refer Repo With sample code:
https://github.com/SSanjeevi/VirtualAssistantDirectlineExtn
Wrote detailed here.
Project file:
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
<NoWarn>NU1701</NoWarn>
<Version>1.0.3</Version>
BotController.cs
private readonly IBotFrameworkHttpAdapter adapter;
public BotController(IBotFrameworkHttpAdapter httpAdapter, IBot bot)
Startup.cs
Configure Services method:
// Register the Bot Framework Adapter with error handling enabled.
// Note: some classes use the base BotAdapter so we add an extra registration that pulls the same instance.
services.AddSingleton<IBotFrameworkHttpAdapter, DefaultAdapter>();
services.AddSingleton<BotAdapter>(sp => sp.GetService<BotFrameworkHttpAdapter>());
// Configure channel provider
Configure method:
using Microsoft.Bot.Builder.Integration.AspNet.Core;
app.UseHsts();
app.UseCors(x => x.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
// Allow the bot to use named pipes.
app.UseNamedPipes(System.Environment.GetEnvironmentVariable("APPSETTING_WEBSITE_SITE_NAME") + ".directline");
Webchat:
let directLineConnection = await window.WebChat.createDirectLineAppServiceExtension({
domain: domainUrl,
token
});
The attached repo code also contains serilog implementation to have logging in log stream in app service where you can see the error logs if you face any issues.
Follow this article and implement serilog in bot api and deploy .
https://www.lkgforit.com/2022/10/troubleshooting-by-writing-logs-at_15.html

Google Admin Setttings API connection for .NET

I've been working with the Google directory API for quite some time now.
However, I need to update SSO settings in the admin settings section of Google. Yes, they say it will be deprecated at some point, but according to a google employee, it's going to be a while before a new API is available and then the old one will be removed.
First, if there is a NUGET package out there, please let me know. I can't seem to find anything that works with the admin settings API: https://developers.google.com/admin-sdk/admin-settings/
My first attempt is getting the SSO settings in Google.
I can use postman to pull this information so I know the API works.
However, I'm running into two issues:
How can I authenticate using the service certificate that I use in the apis.google.directory class?
Anticipating, how do I request access to the admin settings? In directory API, I have the scope enum to select from. If I'm making a manual connection to the API I assume I'll need to call this by hand?
Code
var certificate = new X509Certificate2(serviceAccountCertPath,
serviceAccountCertPassword,
X509KeyStorageFlags.Exportable);
// below the scopes are going to get in my way, right? What is the scope process I need to do for this manually?
credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { DirectoryService.Scope.AdminDirectoryUser,
DirectoryService.Scope.AdminDirectoryGroup,
DirectoryService.Scope.AdminDirectoryOrgunit},
User = _szAdminEmail
}.FromCertificate(certificate));
// I'm not seeing anyway to call the above credentials
using (HttpClient client = new HttpClient())
{
// client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
client.BaseAddress = new Uri(#"https://apps-apis.google.com/a/feeds/domain/2.0/[mydomain]/sso/general");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//client.DefaultRequestHeaders.
HttpResponseMessage response = client.GetAsync("api/Values").Result; // Blocking call!
var products = response.Content.ReadAsStringAsync().Result;
return products.ToString();
}
The admin settings API does not appear to support service account authentication you will need to use Oauth2. Admin Settings Oauth
Your not going to be able to use it very easily using the Google .net client library as that library was designed for use with the Google discovery apis. I dont think the Admin Settings API is a discovery api. You might be able to use the old gdata library for it I am not sure if one exists I have not been able to find it on nuget. If you do find it the old gdata library doesn't support oauth2 which means that you will need to use the new library for that and plug in the gdata library after.
I have only done this before using the Google contacts api I have a tutorial here on how i did it it may help you here
Auth
string clientId = "xxxxxx.apps.googleusercontent.com";
string clientSecret = "xxxxx";
string[] scopes = new string[] { "https://www.googleapis.com/auth/contacts.readonly" }; // view your basic profile info.
try
{
// Use the current Google .net client library to get the Oauth2 stuff.
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, "test"
, CancellationToken.None
, new FileDataStore("test")).Result;
// Translate the Oauth permissions to something the old client libray can read
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.AccessToken = credential.Token.AccessToken;
parameters.RefreshToken = credential.Token.RefreshToken;
RunContactsSample(parameters);
If you cant find the gdata library for it you may have better luck just using the library for authencation and then code the rest of the calls yourself. It returns xml not json.

Authlete api with Identity Server4

We are trying to use Authlete api with Identity Server4 to create and authorize access token but I can't seem to figure out how we can setup with .NET Core?
IdentityServer4 is software written in C#. If you want to call Web APIs of Authlete from C#, you can use authlete-csharp library (which is available as Authlete.Authlete NuGet package). The API reference of authlete-csharp library is available here.
The following are sample implementations of an authorization server & OpenID provider and a resource server which use authlete-csharp library.
csharp-oauth-server - an authorization server & OpenID provider implementation written in C# that supports OAuth 2.0 and OpenID Connect.
csharp-resource-server - a resource server implementation written in C# that includes an implementation of UserInfo Endpoint whose specification is defined in OpenID Connect Core 1.0.
The following article is an introduction to csharp-oauth-server and csharp-resource-server.
"OAuth 2.0 and OpenID Connect implementation in C# (Authlete)"
Basically, if you use Authlete, you don't have to use IdentityServer4. However, if you have strong reasons to use IdentityServer4, some parts of Authlete APIs may work for your purposes.
For example, if you want to use Authlete just as a generator of access tokens, Authlete's /api/auth/token/create API may work.
// An instance of IAuthleteApi interface.
IAuthleteApi api = ......
// Prepare a request to /api/auth/token/create API.
var request = new TokenCreateRequest
{
GrantType = ......,
ClientId = ......,
Subject = ......,
Scopes = ......,
......
};
// Call /api/auth/token/create API.
TokenCreateResponse response = await api.TokenCreate(request);
// If the API call successfully generated an access token.
if (response.Action = TokenCreateAction.OK)
{
// The newly issued access token.
string accessToken = response.AccessToken;
}
If you want to use Authlete as a storage for metadata of client applications, /api/client/* APIs (and "Client ID Alias" feature) may work.
// An instance of IAuthleteApi interface.
IAuthleteApi api = ......
// Prepare a request to /api/client/create API.
var request = new Client
{
ClientName = ......,
Developer = ......,
ClientType = ......,
RedirectUris = ......,
......
};
// Call /api/client/create API. Client ID and client secret
// are automatically generated and assigned by Authlete.
Client client = await api.CreateClient(request);
// You can update client information by calling
// /api/client/update/{clientId} API.
client = await api.UpdateClient(client);
Authlete manages multiple services. Service here is an instance which corresponds to one authorization server & OpenID provider. Even a service itself can be managed by /api/service/* APIs.
// An instance of IAuthleteApi interface.
IAuthleteApi api = ......
// Prepare a request to /api/service/create API.
var request = new Service
{
ServiceName = ......,
Issuer = ......,
SupportedScopes = ......,
......
};
// Call /api/service/create API. A pair of API key and
// API secret to manage the service is automatically
// generated and assigned by Authlete.
Service service = await api.CreateService(request);
// You can update service information by calling
// /api/service/update/{serviceApiKey} API.
service = await api.UpdateService(service);
Although services and client applications can be managed by Authlete APIs, I recommend you use web consoles (Service Owner Console & Developer Console) to manage them.
Many libraries including IdentityServer4 require programming for configuration of an authorization server itself, registration of client applications and database setup. I didn't want to do such things and finally decided to develop not a library but a SaaS (= APIs + permanent storage) in order to free developers from the burden. It was the reason Authlete was born. (I'm a co-founder of Authlete, Inc.)

Resources