Azure Web Job Console application config setting not getting overridden by Azure App Service Config setting - azure-webjobs

I'm running a Dot Net 6.0 Console application as a web job in Azure App Service. I want to override the configuration setting present in apsettings.json file by the one present in Azure App Service Configuration.
This is the code present in the console application to read the configuration
static async Task Main(string[] args)
{
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json").Build();
var testKey = configuration.GetSection($"TestKey").Value;
Console.WriteLine($"TestKey {testKey}");
And this is apsettings.json file
{ "TestKey": "TestValue" }
Application setting in the Azure App Service where console app is deployed as a Web Job
Output from the Web Job

AFAIK, To override the configuration setting in apsettings.json file, add .AddEnvironmentVariables in Program.cs.
I have reproduced in my environment and got the expected results.
Program.cs
var config = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();
var testKey = config.GetSection($"TestName").Value;
Console.WriteLine($"TestKey {testKey}");
appsettings.json
{
"TestName": "TestValue"
}
Application settings in Azure App Service(Portal):
Output:
Before adding .AddEnvironmentVariables:
After adding .AddEnvironmentVariables:

Related

SignalR can't connect when deployed behind AWS EB

I am trying to use SignalR on an application hosted in AWS EB, with an application loadbalancer in front.
It works perfectly fine when I test it locally, but when deployed, the websocket can not establish a connection and returns:
"Error: Failed to start the connection: Error: There was an error with the transport."
And
"There was an error with the transport. at WebSocket.o.onerror [as __zone_symbol__ON_PROPERTYerror]"
I have tried adding a middleware at the very start of my pipeline, that logs if i get a request for my hub, and this works, so I dont think it is the load balancer or anything AWS Related.
If i call the URL with Postman websocket, I get a status code 400.
I have followed the MS guide and added the configuration for JWT auth
jwtTokenOptions.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
// If the request is for our hub...
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/signalr")))
{
// Read the token out of the query string
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
And as I said, it works fine locally. Any suggestions are most welcome
I fixed this by enabling web sockets for the IIS on the eb instance.
I did this by creating an eb extension with the following command
commands:
01_install_websockets_feature:
command: "%SystemRoot%\\System32\\dism.exe /online /enable-feature /featurename:IIS-WebSockets"
ignoreErrors: true

How to connect to ElasticSearch on AWS via reactivesearch-proxy-server

I'm setting up my first ElasticSearch app using ReactiveSearch to connect to an ElasticSearch index I created on AWS.
I'm new to Node.js and most of the technology involved here. I think I have a basic ReactiveSearch app that works but it won't connect to my AWS ElasticSearch index. When I enter a search I get no output and no errors.
I followed the ReactiveSearch Quickstart guide:
https://opensource.appbase.io/reactive-manual/getting-started/reactivesearch.html
I created the Boilerplate App with CRA:
https://github.com/facebook/create-react-app#creating-an-app
The app runs ok but there is no output when I try to search.
Then I saw the note that you have to use a proxy with AWS. I cloned https://github.com/appbaseio-apps/reactivesearch-proxy-server and got that working and I now have a proxy that runs on http://localhost:7777/
My Search App connects to the proxy like this:
<ReactiveBase
app="my-search"
url="http://localhost:7777">
This is the code that sets the target in the proxy. I commented out the authorisation because I'm not using appbase.io.
const options = {
target: 'https://search....ap-southeast-2.es.amazonaws.com',
changeOrigin: true,
onProxyReq: (proxyReq, req) => {
/* proxyReq.setHeader(
'Authorization',
`Basic ${btoa('cf7QByt5e:d2d60548-82a9-43cc-8b40-93cbbe75c34c')}`
);*/
/* transform the req body back from text */
const { body } = req;
if (body) {
if (typeof body === 'object') {
proxyReq.write(JSON.stringify(body));
} else {
proxyReq.write(body);
}
}
}
}
I can see the ReactiveSearch app on my browser at http://localhost:3000
When I type keywords into the search box I see output like this in the proxy app:
Verifying requests ✔ {"preference":"results"}
{"query":{"bool":{"must":[{"bool":{"must":[{"bool":{"should":[{"multi_match":{"query":"cables","fields":["Description"],"type":"best_fields","operator":"or","fuzziness":0}},{"multi_match":{"query":"cables","fields":["Description"],"type":"phrase_prefix","operator":"or"}}],"minimum_should_match":"1"}}]}}]}},"size":50,"_source":{"includes":["*"],"excludes":[]},"from":0}
Verifying requests ✔ {"preference":"SearchBox"}
{"query":{"bool":{"must":[{"bool":{"must":{"bool":{"should":[{"multi_match":{"query":"horse","fields":["Description"],"type":"best_fields","operator":"or","fuzziness":0}},{"multi_match":{"query":"horse","fields":["Description"],"type":"phrase_prefix","operator":"or"}}],"minimum_should_match":"1"}}}}]}},"size":20}
What am I missing to get the connection working? Do I need to add some kind of authentication in AWS and add passwords to the proxy code?
Is there a way to see some debugging info?
Thanks,
Phil

ASP.NET Core Swagger uses incorrect json url when web application is hosted in a subdirectory

I followed these instructions to add swagger to my ASP.NET Core application.
It works fine when I host it as a root website but when I host the app as an alias on an existing website, say myserver.com/myapp, swagger will look for swagger.json at an incorrect URL and report: *Can't read swagger JSON from https://myserver.com/swagger/v1/swagger.json. It should instead use https://myserver.com/myapp/swagger/v1/swagger.json.
The message I get is:
Can't read swagger JSON from https://myserver.com/swagger/v1/swagger.json
How can I configure swashbuckle/swagger to use the application base path and look for the swagger.json file at the right place?
I'm hosting on IIS.
The version of swashbuckle is:
"Swashbuckle": "6.0.0-beta902"
I suspect that I'll have to add something to the app.UseSwaggerUi() in the Configure method in Startup.cs but I'm not sure what.
Startup Configure:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger();
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUi();
}
You can use the ASPNETCORE_APPL_PATH environment variable to get the application basepath.
app.UseSwaggerUI(c =>
{
string basePath = Environment.GetEnvironmentVariable("ASPNETCORE_APPL_PATH");
if (basePath == null) basePath = "/";
c.SwaggerEndpoint($"{basePath}swagger/v1/swagger.json", "My API");
});
I ended up specifying the endpoint explicitly:
app.UseSwagger();
app.UseSwaggerUi(c =>
{
c.SwaggerEndpoint($"/swagger/v1/swagger.json", "MyAPI documentation");
//c.SwaggerEndpoint($"/myapi/swagger/v1/swagger.json", "MyAPI documentation");
});
I've been fooling around with hosting the Web API in IIS and in IIS Express, and I end up having to swap out the endpoint depending on where I am hosting the app.

Serving image assets from S3 with ember-cli-deploy Lightning method

I'm trying to deploy an Ember CLI app using ember-cli-deploy and the 'lightning' deployment method (http://ember-cli-deploy.com/docs/v0.6.x/the-lightning-strategy/).
I've got a redis server to serve my index.html file. I've got my assets uploaded to S3. However my image assets don't seem to be loading properly.
In ember-cli-build.js I have:
var app = new EmberApp(defaults, {
fingerprint: {
prepend: '//path-to-my-S3-bucket/'
}
});
but for some reason images are still being served from the redis server IP. I am getting errors like "Failed to load http://redis-server-url/my-image.jpg". Javascript and CSS files are working fine from S3.
Have I missed something here? Is there another step to this configuration?
Many thanks
I would confirm that fingerprinting is enabled. It is only enabled for 'production' builds by default. You should see an md5 checksum appended to your asset file names. For example, my-image.jpg should be something like my-image-9c2cbd818d09a4a742406c6cb8219b3b.jpg
You can override the default behavior by passing the enabled option:
var app = new EmberApp(defaults, {
fingerprint: {
enabled: true,
prepend: '//path-to-my-S3-bucket/'
}
});

Login failed when a web service tries to communicate with SharePoint 2007

I created a very simple webservice in ASP.NET 2.0 to query a list in SharePoint 2007 like this:
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public string ShowSPMyList()
{
string username = this.User.Identity.Name;
return GetList();
}
private string GetList()
{
string resutl = "";
SPSite siteCollection = new SPSite("http://localhost:89");
using (SPWeb web = siteCollection.OpenWeb())
{
SPList mylist = web.Lists["MySPList"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"AssignedTo\"/><Value Type=\"Text\">Ramprasad</Value></Eq></Where>";
SPListItemCollection items = mylist.GetItems(query);
foreach (SPListItem item in items)
{
resutl = resutl + SPEncode.HtmlEncode(item["Title"].ToString());
}
}
return resutl;
}
}
}
This web service runs well when tested using the built-in server of Visual Studio 2008. The username indicates exactly my domain account (domain\myusername).
However when I create a virtual folder to host and launch this web service (still located in the same machine with SP2007), I got the following error when invoking ShowSPMyList() method, at the line to execute OpenWeb(). These are the details of the error:
System.Data.SqlClient.SqlException: Cannot open database "WSS_Content_8887ac57951146a290ca134778ddc3f8" requested by the login. The login failed.
Login failed for user 'NT AUTHORITY\NETWORK SERVICE'.
Does anyone have any idea why this error happens? Why does the web service run fine inside Visual Studio 2008, but not when running stand-alone? I checked and in both cases, the username variable has the same value (domain\myusername).
Thank you very much.
Thank you very much for the replies. I'll look into the documents to see how i can change the settings related to the application pool as suggested.
I want to make clear that i wanted to build a webservice to run outside of sharepoint (but can be deployed on the same server with sharepoint).
Is there any way i can programmatically pass the credentials (another domain account instead of 'NT AUTHORITY\NETWORK SERVICE' by default) to sharepoint when invoking OpenWeb method? I believe if i'm able to do that then i can walkaround the security issue above.
When you create your own custom virtual folder and set it inside the IIS, it's highly possible that the user account who run the application pool of that particular IIS virtual directory is currently set to NT authority\Network Service.
You can check carefully, by looking closely of what is the actual application pool that run that particular IIS virtual directory.
From there, you can go to the "Application Pool" folder and right click, choose Properties. Select the "Identity" tab, and it will show you who is the user account that currently running the application pool.
Alternatively, you can refer to the SharePoint SDK, something similar to ExtractCrmAuthenticationToken in dynamics CRM to extract the Authentication Token ticket.
Or alternatively you can use Network Credential to embed your own custom user id and password.
Hope this helps,
hadi teo
I fully agree with Hadi, if this is something you want to just quickly test, for a proof of concept, you can change the credentials under what the Application pool runs, to a user that has permissions. Or you could use Identity Impersonate setting in your config file.
However resist the temptiation to do this in a production enviroment, use the proper authentication. It will come back, to bite you.
If you need to set this up for production, there is a couple of areas that you want to look at, duplicate SPN's, and deligation probably the most common areas that is not configured correctly. Your error however points to impersanation not happening.
Also make sure you are deploying the web service to its own web site that does not already run SharePoint. If you want the web service to run on the same web site as SharePoint read Creating a Custom Web Service.
You can check what application pool identity SharePoint is using by following the same instructions that Hadi writes, but for an app pool running SharePoint. Make sure to only change the application pool used by your web service and not SharePoint or else other permission errors could occur within SP. (There should be no reason but if you are interested in changing the app pool identity used by SharePoint follow these instructions.)
On solution would be to "impersonate" as the SharePoint System account using the following code:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// also dispose SPSite
using (SPSite siteCollection = new SPSite("http://localhost:89"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
// ...
}
}
});