Azure fluent management api bind custom root domain to app service - c#

I've been having trouble with this for a while and now I really need help.
This is the code I am currently using to bind a custom subdomain to Azure and everything is working just fine:
var appService = await azure.AppServices.WebApps.GetByIdAsync(
"subscription-id");
await appService.Update().DefineHostnameBinding()
.WithThirdPartyDomain("mydomain.net")
.WithSubDomain("www")
.WithDnsRecordType(CustomHostNameDnsRecordType.CName)
.Attach()
.ApplyAsync();
So what will be the way to bind just mydomain.net except that CustomHostNameDnsRecordType.CName should be changed with CustomHostNameDnsRecordType.A because Azure does not support CNAME records for root domains?
I cannot skip the WithSubDomain(string) method. Tried passing and null/empty string/space or just . but the response from Azure for null is Object reference not set to an instance and for the others is Bad Request.
P.S. I know that I am using an old SDK which is in maintenance mode but the new ones are still in beta or even alpha and there is still no support for App Services so I have to stick with that.

#DeepDave-MT pointed me to the correct answer in a comment under my question even though it's ridiculous. I am now quite sure I will go with this fluent API because there are too many things that are bothering me, almost no documentation, bad error handling and so on. Anyway, this is how to add a root domain in Azure using the so called fluent management API:
await appService.Update().DefineHostnameBinding()
.WithThirdPartyDomain("mydomain.net")
.WithSubDomain("#")
.WithDnsRecordType(CustomHostNameDnsRecordType.A)
.Attach()
.ApplyAsync();
P.S. I don't know why I don't have the habit to check for issues in GitHub.

Related

Generating links to self when running behind reverse proxy

How can I generate absolute links to other resources in my RESTful API app when the app is meant to be accessed via a reverse proxy that publishes just the paths under /api?
My app is an API with a common layout of routes like /api, /swagger and /health. It is published on my employer's API management under a path of the form /business-area/api-name/v1. Calling the API both directly and through the API gateway overall works: calling https://api-gateway.company.com/business-area/api-name/v1/some-resource results in internal call to https://my-app.company.com/api/some-resource.
The issue is that the links in my app's responses point directly to the backend app (https://my-app.company.com/api/another-resource), not the the API gateway (https://api-gateway.company.com/business-area/api-name/v1/another-resource). They are generated using IUrlHelper.
I solved the domain by the ForwardedHeadersMiddleware and adding the X-Forwarded-Host by a policy on the API management. Sadly, we are allowed to use just extremely simple policies, so if we published the API using multiple gateways, the current solution would generate link to just a single one. But that is an issue to be solved somewhen later; now it works OK.
I could not get the path to work well. I tried changing the paths using a middleware as hinted in the ASP.NET Core behind proxy docs:
app.Use((context, next) =>
{
context.Request.PathBase = "/business-area/api-name/v1";
if (context.Request.Path.StartsWithSegments("/api", out var remainder))
{
context.Request.Path = remainder;
}
return next();
});
When I insert this middleware high in the pipeline, it breaks the routing, but if I insert it low enough, the routing works OK and only link generation is affected. But it seems that only PathBase change really affects link generation as the /api is still in the generated URI. I can see that the Path of the request object is really changed, though, so it is probably just that link generation uses the routing info directly, without passing through my middleware, which makes sense, but it rules out the middleware solution.
Is wrapping the standard IUrlHelper in my own implementation and postprocessing the URLs it returns a good way to go? I don't know how to go about that. I use the IUrlHelper from the ControllerBase.Url property and debugger tells it is actually an instance of Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper. Doing the wrapping in every action seems wrong (repetitive, error-prone).
Changing the routing so that /api moves to the root is my last resort option as it mixes up the namespaces: technical endpoints like /health and /swagger would live among the actual resources of the API. Is there a reasonable way to avoid that while keeping the links working? This all seems like a pretty standard problem and I am surprised I cannot find how to solve it.
We use .NET 5 and we will migrate to .NET 6 as soon as it is out, if that makes any difference.

Get remote IP address in DotVVM

I'm building an app using DotVVM framework (ver 1.1.9) using AspNet.Core and .NET Framework 4.7.1.
At some point I need to log remote user's IP address. Is there a way to get it inside the ViewModel? I've seen many tutorials
There is a property Context in ViewModelBase that has property HttpContext but it's some build-in IHttpContext interface, not the proper HttpContext.
However I found out that I can cast existing IHttpContext to DotvvmHttpContext which contains property OriginalContext that indeed seems to be the one I was looking for.
var remoteAddr = ((DotvvmHttpContext)Context.HttpContext).OriginalContext.Connection.RemoteIpAddress;
So the question is, if this is "safe" approach or is there any other "proper" way to either access original AspNet HttpContext or the remote IP Address directly?
Yes, this is safe approach as long as you are only going to run the application on Asp.Net Core. If you'd switch to OWIN hosting for some reason, it would throw an invalid cast exception.
Also note that there is a helper method for getting the Asp.Net Core http context, Context.GetAspNetCoreContext().Connection... might be a bit more comfortable. As you can see from the source code, it's basically the same as your code: https://github.com/riganti/dotvvm/blob/d623ae5ddf57ecf3617eb68454d546f675b64496/src/DotVVM.Framework.Hosting.AspNetCore/Hosting/AspNetCoreDotvvmRequestContextExtensions.cs#L13
Looking at the source for IHttpContext that is exposed in the DotvvmViewModelBase, there does not seem to be a good way to access the connection information. I was hoping that the IHttpRequest might expose the remote IP address but that also isn’t the case.
You have to rely on accessing the original HttpContext from ASP.NET Core here to access that information. If you run on ASP.NET Core (instead of OWIN), then it should be totally save to cast the context to DotvvmHttpContext so that you can access the underlying HttpContext.
So yeah, your solution seems just fine here:
var originalHttpContext = ((DotvvmHttpContext)Context.HttpContext).OriginalContext;

Google Datastore authentication issue - C#

I'm trying to connect to the Google Datastore on my account with service account credentials file (which I've created according to the documentation), but I'm encountering with authentication error while trying to insert an entity:
Grpc.Core.RpcException: Status(StatusCode=Unauthenticated,
Detail="Exception occured in metadata credentials plugin.")
My code is:
var db = DatastoreDb.Create("myprojectid");
Entity entity = new Entity{
Key = db.CreateKeyFactory("mykindname").CreateIncompleteKey()
};
var keys = await db.InsertAsync(new[] { entity });
The GOOGLE_APPLICATION_CREDENTIALS variable refers to the credentials file and when calling GoogleCredential.GetApplicationDefaultAsync() to see if the credentials object is valid it indeed looks good...
I saw some earlier examples which used the GetApplicationDefaultAsync function togehether with some DatastoreService object - but I couldn't find the DatastoreService object (probably it was there in old versions...) in the latest .Net API: Google.Cloud.Datastore.V1
Notice that I don't want to use the other authenticaiton methods:
1) Using the gcloud cli.
2) Running from Google environment (app engine for example).
Any idea how to solve this?
After the great help of Jon Skeet the issue was solved.
The authentication issues can occur if you don't reference all the required Datastore dlls. Make sure that all the dlls are referenced on the project that are running the calls to the Datastore.
I've added the Google Datastore lib via the NuGet to my test project and everything worked!
Notice that in such cases it is recommended to enable gRPC logging. `(For exmaple: GrpcEnvironment.SetLogger(new ConsoleLogger()), there you'll probably see if there were issues loading several dlls...
Authentication can be broken if your system clock is significantly incorrect. Check your system time, and fix it if necessary, then try authenticating against Datastore again.

PayPal Recurring Plan List is NULL

I'm attempting to get a list of all Recurring Payment plans using the C# API. The result is always NULL. What am I doing wrong? I setup and tested other similar API requests such as Invoie.GetAll and that works, so I am confident my user account is setup correctly, I have a good auth token, etc.
Here is my code (note: I've tried passing the optional parameters too with no luck). Perhaps there is a bug with the Api?
var plans = PayPal.Api.Plan.List(_apiContext);
return Xml(plans);
Turns out I needed to use Express Checkout of the NVP and SOAP API Reference. I have something working now.

HttpSelfHostServer and HttpContext.Current

I'm working on a self-hosted ASP.NET web api-application.
Everything works fine, but now I'm struggling with HttpContext:
I need to save session-informations from the client.
But HttpContext.Current is always null.
So it's obvious that my HttpSelfHostServer don't work with the static HttpContext-Class.
The thing I don't understand is: why..?
And I can't figure out a way to tell neither HtttpSelfHostServer nor HttpSelfHostConfiguration to work with HttpContext.
Here's what I'm doing:
Creating a HttpSelfHostConfiguration
1.1 Adding Service-Resolvers & Routes
1.2 Adding custom UserNamePassword-Validator
create new Instance of HttpSelfHostServer with the config
2.1 server.OpenAsync().Wait()
Any help how I can tell my server to work with HttpContext.Current is greatly appreciated!
Cheers!
You won't be able to use HttpContext in a self-hosted environment. HttpContext is set by the ASP.Net pipeline, which you won't have if you don't run under IIS/ASP.Net.
The HttpContext is only available in the Web-Hosting mode, in which the HttpControllerHandler creates the request.
FYI- I invite you to read the following great articles from Pedro Felix to better understand the different hosting models:
HTTP processing architecture overview
Web-hosting
Self-hosting
To get around this problem (I find I am using a lot of components these days that need to work equally well in Web API and MVC), you can try this old shim I wrote to give you back an HttpContext-like interface that works in both flavours. It's on NuGet also, here's the source:
Link on github
(or Link on Nuget)

Categories