Flurl.Http PostMultipartAsync caused some errors - flurl

I'm posting some data to a server. This piece of code works fine a few months ago. But now it threw “Flurl.Http.FlurlHttpException”.
Flurl.Http 2.3.2
string res = "";
try
{
var obj = new { api_key = "key", api_secret = "secret", start = 1 };
res = await "https://api-cn.faceplusplus.com/facepp/v3/faceset/getfacesets"
.PostMultipartAsync(mp => mp
.AddStringParts(obj)
).ReceiveString();
}
catch (FlurlHttpException ex)
{
Debug.WriteLine(ex.Message);
}
The only difference is Win10 version, from 1803 to 1809.
I changed to use "PostUrlEncodedAsync", the server returns success.
But this method can't add a file.
res = await apiUrl
.PostUrlEncodedAsync(obj)
.ReceiveString();
Here is the FlurlHttpException:
{Flurl.Http.FlurlHttpException: Call failed with status code 400 (): POST https://api-cn.faceplusplus.com/facepp/v3/faceset/getfacesets
at Flurl.Http.FlurlRequest.<HandleExceptionAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Flurl.Http.FlurlRequest.<SendAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Flurl.Http.FlurlRequest.<SendAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Flurl.Http.HttpResponseMessageExtensions.<ReceiveString>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at FacePlusPlusUWP.FaceServiceClient.<SendRequestAsync>d__26.MoveNext()}

As indicated by FlurlHttpException.Message, you're getting a 400 (Bad Request) response from the server. I am not familiar with the API you're using, but the first thing I would check is whether the server sent you a helpful response body. You can do that in your catch block like this:
catch (FlurlHttpException ex)
{
var resp = await ex.GetResponseStringAsync();
Debug.WriteLine(resp);
}

Related

HTTP-2 Push Notification using PushSharpHttpTwo

I try to send HTTP-2 Push Notification to Apple using PushSharpHttpTwo. This is the code I use:
var config = new ApnsHttp2Configuration(ApnsHttp2Configuration.ApnsServerEnvironment.Production, certificate, password);
var broker = new ApnsHttp2ServiceBroker(config);
broker.Start();
foreach (Device device in deviceCollection)
{
broker.QueueNotification(new ApnsHttp2Notification
{
DeviceToken = device.Token,
Topic = "com.nnnn.nnnnnn",
Payload = JObject.Parse("{ \"aps\" : { \"alert\" : \"Hello PushSharp!\" } }")
});
}
broker.Stop();
This result in the following error:
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message received was unexpected or badly formatted --- End of inner exception stack trace --- at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at HttpTwo.Http2Connection.d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at HttpTwo.Http2Client.d__19.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at HttpTwo.Http2Client.d__17.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at HttpTwo.Http2Client.d__15.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at PushSharp.Apple.ApnsHttp2Connection.d__10.MoveNext() in C:\Users\MyUser\Folder\PushSharpHttpTwo\PushSharpHttpTwo-master\PushSharp.Apple\ApnsHttp2Connection.cs:line 99 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at PushSharp.Apple.ApnsHttp2ServiceConnection.d__2.MoveNext() in C:\Users\MyUser\Folder\PushSharpHttpTwo\PushSharpHttpTwo-master\PushSharp.Apple\ApnsHttp2ServiceConnection.cs:line 40
After doing some research, it seems like the error has to do with wrong TLS. Or, do anyone know why I get the error above?
PS: when using the following code (without HTTP-2), Apple Push notification work fine:
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production, certificate, password);
var apnsBroker = new ApnsServiceBroker(config);
apnsBroker.Start();
foreach (Device device in deviceCollection)
{
apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = device.Token,
Payload = JObject.Parse("{ \"aps\" : { \"alert\" : '" + alert + "', \"badge\" : '" + AddBadge(device) + "', \"sound\" : \"default\" }}")
});
}
apnsBroker.Stop();
My website run framework 4.7.2.
I had the same error for various errors linked to my certificate.
From my experience, it could be that the certificate you are using is expired.
I also had the problem while using the .cert file instead of the .p12 file.

Java.Net.SocketException Error: Socket closed in System.net.Http httpClient, occurs only when sending files larger than 50kbs

I am making a program in xamarin, which uses http requests to get data from an API made in net.core 2.0, but some requests (most of them actually) culminate in the following error:
System.AggregateException: One or more errors occurred. ---> Java.Net.SocketException: Socket closed
at Java.Interop.JniEnvironment+InstanceMethods.CallIntMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Java.Net.HttpURLConnection.get_ResponseCode () [0x0000a] in <b781ed64f1d743e7881ac038e0fbdf85>:0
at Xamarin.Android.Net.AndroidClientHandler+<>c__DisplayClass45_0.<DoProcessRequest>b__1 () [0x00000] in <b781ed64f1d743e7881ac038e0fbdf85>:0
at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.Execute () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
--- End of stack trace from previous location where exception was thrown ---
at Xamarin.Android.Net.AndroidClientHandler+<DoProcessRequest>d__45.MoveNext () [0x0036c] in <b781ed64f1d743e7881ac038e0fbdf85>:0
--- End of stack trace from previous location where exception was thrown ---
at Xamarin.Android.Net.AndroidClientHandler+<SendAsync>d__40.MoveNext () [0x00230] in <b781ed64f1d743e7881ac038e0fbdf85>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <25ebe1083eaf4329b5adfdd5bbb7aa57>:0
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task`1[TResult].GetResultCore (System.Boolean waitCompletionNotification) [0x0002b] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task`1[TResult].get_Result () [0x0000f] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at FonoApp.Services.DataService.SendImageAsync (System.String token, FonoApp.Model.Imagem imagem) [0x00059] in C:\Projetos Sorri\FonoApp\AppTeste\AppTeste\Services\DataService.cs:154
--- End of inner exception stack trace ---}
This error occurs in this code snippet:
public async Task<String> SendImage(string token, Imagem imagem)
{
string baseAddress = #"http://192.168.0.4:5000/" + VersaoApi + #"/Imagem/";
var json = JsonConvert.SerializeObject(imagem);
var contentString = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
try
{
HttpResponseMessage tokenResponse = client.PostAsync(baseAddress, contentString).Result;//Erro ocorre nesta linha
var jsonContent = tokenResponse.Content.ReadAsStringAsync().Result;
return jsonContent;
}
catch (Exception e)
{
return e.InnerException.Message.ToString();
}
}
From what I researched, and discovered from this error, means that the connection is being closed either by the server or by the client, but I can't even know who closes the connection suddenly let alone prevent this / exception error, I don't know if it matters but I am testing the app on an android 4.2-API 17 tablet. Thanks in advance for any guidance on this as I am still learning how to program in C #.
one thing I forgot to say before was that Postman API requests work without problems
I noticed something interesting the error I get only occurs when trying to send images larger than 100 kb by http request, how can I increase the send and receive weight limit on my server?
Firstly, you need to use await instead of Result() to make this method async:
var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
And yes, this exception occurs when internet connection is lost. You can do these things to make your app more usable:
Display a warning message in try-catch block
Check internet connection by using Xamarin.Essentials.Connectivity plugin
Set a timeout for your HttpClient object and catch the TimeoutException to display proper message

Is there a way to configure "JwtBearerOptions" on netcore webapi application?

I'm implementing a dotnet core webapi application. It uses Jwt bearer authentication and Azure Active directory.
The web server uses a proxy to access Internet.
I'm facing some problems to configure authentication service behind a proxy.
Using AddAzureADBearer extension and Postconfigure does not work for me.
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => {
Configuration.Bind("AzureAd", options);
});
services.PostConfigure<JwtBearerOptions(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.BackchannelHttpHandler = new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Address = new Uri("http://10.10.10.10:8080"),
BypassProxyOnLocal = true,
},
};
});
Exception Details :
fail: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[3]
Exception occurred while processing message.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'.
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
fail: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[3]
Exception occurred while processing message.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.OperationCanceledException: The operation was canceled.
at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'.
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.OperationCanceledException: The operation was canceled.
at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
fail: Fdp.Webshell.Web.Startup[0]
Something went wrong
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'.
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 59994.808ms 500 application/json
fail: Fdp.Webshell.Web.Startup[0]
Something went wrong
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.OperationCanceledException: The operation was canceled.
at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 60013.4769ms 500 application/json
Replace this code :
services.PostConfigure<JwtBearerOptions(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.BackchannelHttpHandler = new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Address = new Uri("http://10.10.10.10:8080"),
BypassProxyOnLocal = true,
},
};
});
By this code :
services.Configure<JwtBearerOptions(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.BackchannelHttpHandler = new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Address = new Uri("http://10.10.10.10:8080"),
BypassProxyOnLocal = true,
},
};
});

ReplaceDocumentCollectionAsync throwing DocumentClientException

Trying to update the IndexingPolicy of a collection. The collection definition works fine when using CreateDocumentCollectionIsNotExistsAsync, but when trying to update the definition of an exising collection using ReplaceDocumentCollectionAsync, a DocumentClientException is thrown. using .NET library 1.19.1. Exception details are:
DocDBTrace Error: 0 : DocumentClientException with status code NotFound, message: The value '' specified for query '$resolveFor' is invalid., inner exception: null, and response headers: null
DocDBTrace Error: 0 : Operation will NOT be retried. Current attempt 0, Exception: Microsoft.Azure.Documents.NotFoundException: The value '' specified for query '$resolveFor' is invalid., documentdb-dotnet-sdk/1.19.1 Host/64-bit MicrosoftWindowsNT/6.2.9200.0
at Microsoft.Azure.Documents.DocumentServiceRequest..ctor(OperationType operationType, ResourceType resourceType, String path, Stream body, AuthorizationTokenType authorizationTokenType, NameValueCollection headers)
at Microsoft.Azure.Documents.DocumentServiceRequest.Create(OperationType operationType, String relativePath, Resource resource, ResourceType resourceType, AuthorizationTokenType authorizationTokenType, NameValueCollection headers, SerializationFormattingPolicy formattingPolicy, JsonSerializerSettings settings)
at Microsoft.Azure.Documents.Client.DocumentClient.<ReplaceDocumentCollectionPrivateAsync>d__123.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Documents.BackoffRetryUtility`1.<>c__DisplayClass2.<<ExecuteAsync>b__0>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Documents.BackoffRetryUtility`1.<ExecuteRetry>d__1b.MoveNext()
Updated with code. I'm trying to share the creation/modify index code, so I call CreateDocumentCollectionIfNotExistAsync first and if the collection exists, then I modify the index policy to match the latest.
DocumentCollection appCollection = new DocumentCollection();
appCollection.Id = CosmosDbCollectionName;
// Set the index policy
var rrdc = await cdbClient.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(CosmosDbDatabaseName), appCollection);
if (true == rrdc.StatusCode.IsSuccessCode())
{
// If OK was returned, the collection already existed.
if (HttpStatusCode.OK == rrdc.StatusCode)
{
var rr = await _cdbClient.ReplaceDocumentCollectionAsync(appCollection).ConfigureAwait(false);
if (false == rr.StatusCode.IsSuccessCode())
return false;
}
}
You need to pass the DocumentCollection resource instance returned from CreateDocumentCollectionIfNotExistsAsync to ReplaceDocumentCollectionAsync.
For example:
DocumentCollection appCollectionSpec = new DocumentCollection();
appCollection.Id = CosmosDbCollectionName;
// Set the index policy
ResourceResponse<DocumentCollection> rrdc = await cdbClient.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(CosmosDbDatabaseName), appCollectionSpec);
if (true == rrdc.StatusCode.IsSuccessCode())
{
// If OK was returned, the collection already existed.
if (HttpStatusCode.OK == rrdc.StatusCode)
{
var rr = await _cdbClient.ReplaceDocumentCollectionAsync(rrdc.Resource).ConfigureAwait(false);
if (false == rr.StatusCode.IsSuccessCode())
return false;
}
}
I don't believe the DocumentCollection instance that is passed to CreateDocumentCollectionIfNotExists is modified by the call, as it is treated as a 'spec' object. The replace operation requires internal metadata that is only populated by resources returned from the server.

asp net core project MVC controllers using Cookie Authentication and api end points using Bearer

I am working on a project using ASP .net CORE, where we have Angular 2 and MVC and API, need to be protected by Azure AD.
Home/Index MVC controller will start the Angular 2 SPA and Home/Index need to be protected by cookie authentication. I manage to get the token using the OpenIdConnectAuthentication - OnAuthorizationCodeReceived event.
I need to protect the MVC controllers (there are few more controllers apart from Home/Index) using Cookie based Authentication and API using Bearer Authentication, I can get the token from API to Angular then use that token for each subsequent call to API.
In the near future there will be mobile apps calling the same API end points, using Bearer tokens.
This was my starting point:
https://learn.microsoft.com/en-us/azure/active-directory/active-directory-appmodel-v2-overview
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddJsonOptions(config => { config.SerializerSettings.ContractResolver = new DefaultContractResolver(); });
services.AddAuthentication(sharedOptions => sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions());
Authority = $"https://login.microsoftonline.com/AAAAA}";
ClientId = "BBBB";
ClientSecret = "CCCC";
Audience = "https://localhost:44333/";
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = ClientId,
Authority = Authority,
PostLogoutRedirectUri = Audience,
ResponseType = OpenIdConnectResponseType.CodeIdToken,
GetClaimsFromUserInfoEndpoint = false,
Events = new OpenIdConnectEvents
{
OnTokenValidated = TokenValidated,
OnRemoteFailure = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived
}
});
app.UseMvc(....);
}
Question:
How can I configure the API to use just "Bearer" auth and MVC to use Cookies?
Update
Hi Adem
Thank you for your reply.
I never tired 1st option, will give it a go now.
but I have tired 2nd option earlier, and just tired it as below.
Added this below app.UseOpenIdConnectAuthentication(...
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
Authority = "https://login.microsoftonline.com/AAAA",
Audience = "https://BBB.onmicrosoft.com/CCCC"
});
For API Controller [Authorize(ActiveAuthenticationSchemes = "Bearer")]
For MVC Controller [Authorize(ActiveAuthenticationSchemes = "Cookies")]
When it hits my Home Controller it get this error
Specified method is not supported.
this Stack Trace
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.HandleSignInAsync(SignInContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler1.d__66.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Http.Authentication.Internal.DefaultAuthenticationManager.d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.<HandleRemoteCallbackAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.d__6.MoveNext()
Update 2:
I have tired configuring 2 different auth for APIand MVC like below
app.UseWhen(context =>
context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
Authority = Authority,
Audience = Configuration["Authentication:AzureAd:Audience"]
});
});
app.UseWhen(context =>
!context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = ClientId,
Authority = Authority,
PostLogoutRedirectUri = Audience,
ResponseType = OpenIdConnectResponseType.CodeIdToken,
GetClaimsFromUserInfoEndpoint = false,
Events = new OpenIdConnectEvents
{
OnTokenValidated = TokenValidated,
OnRemoteFailure = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived
}
});
});
But API still seem to be using the cookie auth. I could still see the the request has cookies in the request.
Thank you
Asanka
One way is to branch application like this:
app.UseWhen(context => <isApiRequest>, appBuilder =>
{
appBuilder.UseJwtBearerAuthentication();
}
app.UseWhen(context => <isNotApiRequest>, appBuilder =>
{
appBuilder.UseCookieAuthentication();
}
note: you could branch your api with "/api" prefix, in this case <isApiRequest> would be context.Request.Path.StartsWithSegment("/api")
Another way is to use AuthenticationScheme:
app.UseCookieAuthentication(//....);
app.UseJwtBearerAuthentication(//...);
Then in api action use Bearer scheme:
[Authoırize(ActiveAuthenticationSchemes = "Bearer")]
public IActionResult ApiAction(){}
For mvc actions use Cookies scheme
[Authoırize(ActiveAuthenticationSchemes = "Cookies")]
public IActionResult MvcAction(){}

Resources