DiscoveryFailedException for the newly created Azure App Registration - azure-active-directory

Recently we have done new App Registration which is exactly same as the previous App Registrations. And, we landed in the issue to use Microsoft.Office365.Discovery v1.0.22 NuGet service discovery library for Office 365 APIs.
Exception of type 'Microsoft.Office365.Discovery.DiscoveryFailedException' was thrown
at Microsoft.Office365.Discovery.DiscoveryClient.d__4.MoveNext()\r\n---
End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at Microsoft.Office365.Discovery.DiscoveryClient.d__14.MoveNext()\r\n---
End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n
Code
var result = new Dictionary<String, AuthenticationResult>();
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticationContext authContext = new AuthenticationContext(string.Format("{0}/{1}", "https://login.windows.net", tenantId));
//authenticate discovery so we can auth all endpoints
var discoveryAccess = authContext.AcquireTokenByAuthorizationCode(authorizationCode, redirectUri, credential, m_sDiscoverySvcResourceId);
result.Add(m_sDiscoverySvcResourceId, discoveryAccess);
//discover endpoints
try
{
DiscoveryClient discClient = new DiscoveryClient(m_uriDiscoverySvcEndpointUri, () => { return discoveryAccess.AccessToken; });
var services = await discClient.DiscoverCapabilitiesAsync();
foreach (var service in services)
{
var srvId = service.Value.ServiceResourceId;
result[srvId] = discoveryAccess;
}
}
catch (DiscoveryFailedException e)
{
Debugger.Break();
}
return result;
same code runs fine with previously created App Registrations. Appreciate any help

Related

Why Compensate method doesn't Call when a consumer thrown exception in MassTransit RouterSlip

I've built a router slip inside a saga state machine :
var builder = new RoutingSlipBuilder(NewId.NextGuid());
var submitOrderUrl = QueueNames.GetActivityUri(nameof(SubmitOrderActivity));
builder.AddActivity("SubmitOrder", submitOrderUrl, new
{
context.Message.OrderId
});;
builder.AddActivity("Payment", QueueNames.GetActivityUri(nameof(PaymentActivity)), new {
context.Message.OrderId,
context.Message.CustomerId,
context.Message.Credit
});
builder.AddActivity("TakeProduct", QueueNames.GetActivityUri(nameof(TakeProductActivity)), new
{
context.Message.OrderId,
Baskets
});
builder.AddVariable("OrderId", context.Message.OrderId);
var routingSlip = builder.Build();
await context.Execute(routingSlip);
And I have TakeProductActivity activity :
public class TakeProductActivity : IActivity<TakeProductArgument, TakeProductLog>:
...
public async Task<ExecutionResult> Execute(ExecuteContext<TakeProductArgument> context)
{
logger.LogInformation($"Take Product Courier called for order {context.Arguments.OrderId}");
var uri = QueueNames.GetMessageUri(nameof(TakeProductTransactionMessage));
var sendEndpoint = await context.GetSendEndpoint(uri);
await sendEndpoint.Send<TakeProductTransactionMessage>(new
{
ProductBaskets = context.Arguments.Baskets
});
return context.Completed(new { Baskets = context.Arguments.Baskets, OrderId=context.Arguments.OrderId });
}
When I use sendEndpoint.Send() method (fire & forget), when an exception occurred in the service, compensate method doesn't activate automatically,
But when I use requestClient.GetResponse (request/reply) method to call service, when an exception occurred automatically Compensate method is called.
and in PaymentConsumer when an exception is thrown it must be compensated methods for payment called but it doesn't!
///this class has implemented in another micro-service hosted separate process:
public class TakeProductTransactionConsumer : IConsumer<TakeProductTransactionMessage>
....
public async Task Consume(ConsumeContext<TakeProductTransactionMessage> context)
{
if(context.Message.ProductBaskets.Count>0)
{
throw new Exception("Process Failed!");
}
logger.LogInformation($"Take product called ");
Dictionary<int, int> productCounts = new Dictionary<int, int>();
foreach (var item in context.Message.ProductBaskets)
{
productCounts.Add(item.ProductId, item.Count);
}
var products = await productService.TakeProducts(productCounts);
await publishEndpoint.Publish<ProductsUpdatedEvent>(new
{
ProductUpdatedEvents = products.Select(p =>new { ProductId = p.Id,p.Price,p.Count}).ToList()
});
}
the problem is that MassTransit couldn't fetch Exception from rabbitMQ and automatically call compensate methods.
How should I say to MassTransit to call compensate when the exception is thrown in router slip activities
If your Take Product activity uses Send to fire-and-forget to the take product service, and that service throws an exception, the activity will never know about it because it's already completed. Fire-and-forget is just that, no exceptions within the destination service are observed.
If you want the take product activity to fail when the take product service throws an exception, you need to use request/response to observe the exception from the service.

How to get access token in typed HttpClient

I've got a IdentityServer4/WebAPI setup and a typed HttpClient in my server-side Blazor application. I want to add the access token dynamically when a request to the API is made. But neither the HttpContext nor the AuthenticationStateProvider is accessible in the AddHttpClient method or in the AddHttpMessageHandler.
This works locally but running on the server httpContextAccessor is null:
services.AddHttpClient<IMyClient, MyClient>((serviceProvider, client) =>
{
var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
var accessToken = await httpContextAccessor.HttpContext.GetTokenAsync("access_token");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}).AddHttpMessageHandler<MyApiBearerTokenHandler>();
Trying to access the AuthenticationStateProvider
services.AddHttpClient<IMyClient, MyClient>((serviceProvider, client) =>
{
var authStateProvider = serviceProvider.GetService<AuthenticationStateProvider>();
}).AddHttpMessageHandler<MyApiBearerTokenHandler>();
throws the following error:
'Cannot resolve scoped service
'Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider'
from root provider.'
How do I get the access token into AddHttpClient? Am I completely on the wrong track?

AuthenticationCertCallback does not work under Ubuntu / docker

I have problem with Certificate Key Vault authentication. In general, it works fine under my pc (win10), but when I run the same code under ubuntu/ docker I receive null reference exception. (On both environments, the certificate is present)
private async Task<string> AuthenticationCertCallback(string authority, string resource, string scope)
{
try
{
var clientAssertionCertPfx = CertificateHelper.FindCertificateByThumbprint(_options.KeyVaultOptions.CertThumb);
var assertionCert = new ClientAssertionCertificate(_options.KeyVaultOptions.Id, clientAssertionCertPfx);
var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
var token = await context.AcquireTokenAsync(resource, assertionCert);
return token.AccessToken;
}
catch (Exception ex)
{
Log.Error(ex, "Failed to acquire the certificate");
return string.Empty;
}
}
I use Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.2.0"
had anyone same problem ?
Ok, so the issue is with GetRSAPrivateKey() from X502Certificate2 class as it returns null under .net core

Microsoft Botframework V4 Virtual Assistant Azure AD Authentication

I have downloaded, configured and deployed the Microsoft Virtual Assistant open source project from GitHub here: https://github.com/Microsoft/AI
I want to start with the calendar skill and have configured everything.
When I request my current calendar entries, the authentication prompt is shown in the botframework emulator and I am able to authenticate with my Azure AD Account.
After that, there is silence...
In SummaryDialog.cs in the CalendarSkill there is a definition for a WaterfallStep like this:
var showSummary = new WaterfallStep[]
{
GetAuthToken,
AfterGetAuthToken,
ShowEventsSummary,
CallReadEventDialog,
AskForShowOverview,
AfterAskForShowOverview
};
The step GetAuthToken is executed, but then execution stops. AfterGetAuthToken is not called at all.
This is the GetAuthToken function inside the project:
protected async Task<DialogTurnResult> GetAuthToken(WaterfallStepContext sc, CancellationToken cancellationToken)
{
try
{
var skillOptions = (CalendarSkillDialogOptions)sc.Options;
// If in Skill mode we ask the calling Bot for the token
if (skillOptions != null && skillOptions.SkillMode)
{
// We trigger a Token Request from the Parent Bot by sending a "TokenRequest" event back and then waiting for a "TokenResponse"
// TODO Error handling - if we get a new activity that isn't an event
var response = sc.Context.Activity.CreateReply();
response.Type = ActivityTypes.Event;
response.Name = "tokens/request";
// Send the tokens/request Event
await sc.Context.SendActivityAsync(response);
// Wait for the tokens/response event
return await sc.PromptAsync(SkillModeAuth, new PromptOptions());
}
else
{
return await sc.PromptAsync(nameof(MultiProviderAuthDialog), new PromptOptions());
}
}
catch (SkillException ex)
{
await HandleDialogExceptions(sc, ex);
return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs);
}
catch (Exception ex)
{
await HandleDialogExceptions(sc, ex);
return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs);
}
}
Am I doing anything wrong in the code or is there anything missing in my configuration?
I found out, if ngrok is not on the PC and configured, the virtual Assistatn does not work.

Timeout while fetching for remoteApi GAE

I'm using Java to implement remoteAPi in Google App Engine (GAE) by following this tutorial:
https://developers.google.com/appengine/docs/java/tools/remoteapi
but after configuring at web.xml, I use the following codes to insert new entity to local datastore:
String username = "myusername";
String password = "mypassword";
RemoteApiOptions options = new RemoteApiOptions()
.server("localhost", 8888)
.credentials(username, password);
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
try {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
System.out.println("Key of new entity is " +
ds.put(new Entity("Hello Remote API!")));
} finally {
installer.uninstall();
}
but error has occured:
Problem accessing /remoteApi/index. Reason:
Timeout while fetching: http://localhost:8888/remote_api
I viewed on debug and know that it caused by : "installer.install(options);" statement.
How can I solve this? Increase the socket time out ?
Thank in advance !
i did it in both local and also deployed apps.following code may help you.
remember the code must be write in RPC
i used GWT 2.4,JRE 1.7 and GAE 1.7.2.
put GAE Remote Api in WEB-INF/lib
web.xml
<servlet>
<display-name>Remote API Servlet</display-name>
<servlet-name>RemoteApiServlet</servlet-name>
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RemoteApiServlet</servlet-name>
<url-pattern>/remote_api</url-pattern>
</servlet-mapping>
XyzServiceImpl.java
#Override
public String callGaeRemote() {
RemoteApiInstaller installer = null;
List<Entity> allEntities = null;
String response = null;
try {
RemoteApiOptions options = new RemoteApiOptions().server(
"localhost", 8888).credentials(
"username", "password");
installer = new RemoteApiInstaller();
installer.install(options);
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
System.out.println("Key of new entity is " +
ds.put(new Entity("Hello Remote API!")));
response = "Success";
} catch (IOException e) {
e.printStackTrace();
}
finally {
installer.uninstall();
}
return response;
}

Resources