Authentication from Development to Release - visual-studio

I have a small web project to develop for a friend that will be incorporated into a small existing website using Visual Studio 2015.
A user has to be logged in, requiring a secure connection. I cannot use the existing website to authenticate with their SSL/Certificate during development because the URL will not be the same (or at least I don't know how).
Social media logins or traditional email/password logins can get involved to implement (new user, existing user, lost passwords, change passwords). I have only done it once before, so I would rather not have to change all of those settings from the development site to the existing site after it all gets working.
How do experienced people do this?

I would solve it using separate configuration files for each environment.
Each environment has specific configuration in its own file:
Each config file can have different security-concen configuration:
appsettings.Local.json
{
"TokenValidationConfig": {
"ValidAuthority": "https://localhost:8394",
"RequireHttpsMetadata": "false"
},
"HttpsConfig": {
"CertificateIdentifier": "Unnecessary for local env"
}
}
appsettings.Prod.json
{
"TokenValidationConfig": {
"ValidAuthority": "https://xxx.xxx.com"
},
"HttpsConfig": {
"CertificateIdentifier": "https://xxx.xxx.vault.azure.net/secrets/wildcard-xxx-xxx"
}
}
Current environment is specified in environment variable, and then is read on startup:
new WebHostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
var envName = hostingContext.HostingEnvironment.EnvironmentName;
config
.AddJsonFile(
path: "appsettings.json",
optional: false,
reloadOnChange: false)
.AddJsonFile(
path: $"appsettings.{envName}.json",
optional: false,
reloadOnChange: false);
Consider official documentation on the matter:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#json-configuration-provider

Related

MVC Core Windows Authentication not working

I'm trying to set up an MVC Core Web App with Windows Authentication in Visual Studio 2022 but I can't get it to work.
I create a new project and select the Windows Authentication option. I immediately try to run the app but I get a blank page.
For troubleshooting I then added the following else clause so I can see what the problem is on my development machine.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
else
{
// Development Environment
app.UseStatusCodePages();
}
and I can then see that I have a '401 Unauthorised' status code. And then if I add [AllowAnonymous] to my Index action I can finally see the home page but my windows username is not displayed. I would expect to see 'Hello username' displayed in the top right but I don't seem to be authenticated, let alone authorized.
Apart from the two troubleshooting steps above, this is a brand new project straight out of the box but I've pasted my Program.cs below for reference.
What do I need to do to get Windows Authentication to work?
Thanks
using Microsoft.AspNetCore.Authentication.Negotiate;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
else
{
// Development Environment
app.UseStatusCodePages();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
You can follow my steps to fix the issue.
Enable IIS features in your develop machine, this just want to enable Windows authentication on Windows.
Tips: Please expand all the fields and tick them, then click Apply.
Delete the .vs folder inside your project, this steps just want to reset the applicationhost.config.
The latest step, we need to double check the settings file in project.
Then the issue should be fixed now.

How do environment variables and appSettings file(s) get used during publish?

If I have two settings files
appSettings.json and appSettings.Development.json
When I use publish from Visual Studio, are both supposed to be copied to the target folder? I'm not sure, because they both show up in the target folder (on a dev server) when I publish. I was under the impression that they combined at build time and ONLY the appSettings.json file was published. If not, then do I need to consider manually coding for these differences as Ive seen in a few examples ?
eg. This example is loading the settings via code (NOT how Im doing it)
Note - they are using the environment name, ASPNETCORE_ENVIRONMENT setting
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
Some of my Startup class is shown below.
Note: I am not referencing the environment setting.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
[ Update ]
I found my answer here - the key I was missing was updating the csproj file for the publish settings related to environment.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-2.2#configuration-with-webconfig
So I assume that if I have several different environments, each with its own settings file, that a publish would result in putting ALL of them out to the target dir?
It's a bit confusing with ASP.NET Core, especially if you're coming from having worked with ASP.NET previously. The build configurations (Debug, Release) really have no bearing on anything that happens with ASP.NET Core. An ASP.NET Core app is technically environment-agnostic. Whereas with an older ASP.NET app, you'd have to publish for a specific environment, you can theoretically take the same ASP.NET Core publish and run it in any of your environments. This is of course aided by the fact that Web.config is not utilized by ASP.NET Core.
This, then, is the reason why all the environment-specific JSON files come along for the ride. Which is ultimately used is based on the value of the ASPNETCORE_ENVIRONMENT environment variable set at runtime, not which build configuration you chose when publishing. Which is actually really nice when you think about it. You can take the same published app, run it in your "staging" environment to ensure everything is working and then deploy it to your "production" environment, simply by ensuring that each environment has the appropriate value for ASPNETCORE_ENVIRONMENT set. This makes release pipelines trivial.
That said, it's still possible to use things like the #if DEBUG compiler directives, and if you do that then there will be differences in your ASP.NET Core app depending on the build configuration chosen, but you should really avoid doing that in the first place. In general, you should rely only on the IHostingEnvironment abstraction in an ASP.NET Core app to determine what happens in what environment.

How To Disable Https in Visual Studio 2017 Web Proj ASP.NET Core 2.0

I've created a default project in Visual Studio 2017 with ASP.NET Core 2.0. I've chosen the Web App with MVC and with Individual Use Auth. By default, it is coming up configured and working with https. I've tried disabling that by going into project properties and removing the user ssl and changing https to http but then I get either and IIS Express Connection error or a 404.
I've not see default https before. Where is that coming from and where can I disable it?
Update .Net 6
If you stumbled across this question, but are looking to disable SSL in .Net 6, follow these instructions:
Disable SSL redirection by removing app.UseHttpsRedirection();
(optional) define a default port to listen to with app.Run("http://localhost:5000"); If omitted, a random port will be assigned.
Original answer for .Net Core 2.0:
I've just created a default MVC app using net core 2.0.
To disable SSL, you need to do 2 steps. You can do this either by using the Visual Studio GUI, or by editing the launchsettings.json (further down)
go to your project properties
In the Debug category uncheck the SSL option
Copy the App Url over to the Start browser input
Et voila:
If you are not a fan of using the interface, you can alternatively edit the launchsettings.json file, by setting sslPort: 0 and "launchUrl": "http://localhost:13121/" (or where ever you want to launch the application)
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:13121/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "http://localhost:13121/",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebApplication1": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:13122/"
}
}
}
I was just having this same issue (ie. I needed a non-SSL URL to establish a working ngrok.com tunnel)
There's probably an alternative unsecured localhost URL defined.
I realize the question is to disable the secured one, but you probably don't need to. You probably already have an unsecured one defined.
Admittedly, I inherited this project so I'm not aware if a default project would be configured the same. My assumption is that there's an unsecured URL already available for you that you might be overlooking.
If I'm wrong this answer seems good (Ngrok errors '502 bad gateway'), but again I didn't need to try it.
Just look in the "Development Server" properties.
See my screenshot below:
Go to App Properties and uncheck "Enable SSL"
If the answer provided by #Marco didn't resolved the issue you can try this,
When you create new .net core mvc application there will be default meta tag generated in _Layout cshtml to upgrade the http request to https ( "http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"). When you deploy your application to server without http you may need to remove the below tags
http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"
Also comment the below line from Startup.cs file
app.UseHttpsRedirection();
It's most likely in your publish settings.
I had this issue and I simply went to the publish settings and discovered that after the build, the publish url contained https.

apiKey key ID and secret is required even though they're there in express-stormpath

I'm trying to use express-stormpath on my Heroku app. I'm following the docs here, and my code is super simple:
var express = require('express');
var app = express();
var stormpath = require('express-stormpath');
app.use(stormpath.init(app, {
website: true
}));
app.on('stormpath.ready', function() {
app.listen(3000);
});
I've already looked at this question and followed the Heroku devcenter docs. The docs say that for an Heroku app, it's not necessary to pass in options, but I've still tried passing in options and nothing works. For example, I've tried this:
app.use(stormpath.init(app, {
// client: {
// file: './xxx.properties'
// },
client: {
apiKey: {
file: './xxx.properties',
id: process.env.STORMPATH_API_KEY_ID || 'xxx',
secret: process.env.STORMPATH_API_KEY_SECRET || 'xxx'
}
},
application: {
href: 'https://api.stormpath.com/v1/applications/blah'
},
}));
To try and see what's going on, I added a console.log line to the stormpath-config strategy valdiator to print the client object, and it gives me this:
{ file: './apiKey-xxx.properties',
id: 'xxx',
secret: 'xxx' }
{ file: null, id: null, secret: null }
Error: API key ID and secret is required.
Why is it getting called twice, and the second time around, why does the client object have null values for the file, id and secret?
When I run heroku config | grep STORMPATH, I get
STORMPATH_API_KEY_ID: xxxx
STORMPATH_API_KEY_SECRET: xxxx
STORMPATH_URL: https://api.stormpath.com/v1/applications/[myappurl]
I'm the original author of the express-stormpath library, and also wrote the Heroku documentation for Stormpath.
This is 100% my fault, and is a documentation / configuration bug on Stormpath's side of things.
Back in the day, all of our libraries looked for several environment variables by default:
STORMPATH_URL (your Application URL)
STORMPATH_API_KEY_ID
STORMPATH_API_KEY_SECRET
However, a while ago, we started upgrading our libraries, and realized that we wanted to go with a more standard approach across all of our supported languages / frameworks / etc. In order to make things more explicit, we essentially renamed the variables we look for by default, to:
STORMPATH_APPLICATION_HREF
STORMPATH_CLIENT_APIKEY_ID
STORMPATH_CLIENT_APIKEY_SECRET
Unfortunately, we did not yet update our Heroku integration or documentation to reflect these changes, which is why you just ran into this nasty issue.
I just submitted a ticket to our Engineering team to fix the names of the variables that our Heroku addon provisions by default to include our new ones, and I'm going to be updating our Heroku documentation later this afternoon to fix this for anyone else in the future.
I'm sincerely sorry about all the confusion / frustration. Sometimes these things slip through the cracks, and experiences like this make me realize we need better testing in place to catch this stuff earlier.
I'll be working on some changes internally to make sure we have a better process around rolling out updates like this one.
If you want a free Stormpath t-shirt, hit me up and I'll get one shipped out to you as a small way to say 'thanks' for putting up with the annoyance: randall#stormpath.com
After endless hours, I managed to finally get it working by removing the add-on entirely and re-installing it via the Heroku CLI and then exporting variables STORMPATH_CLIENT_APIKEY_ID and STORMPATH_CLIENT_APIKEY_SECRET. For some reason, installing it via the Heroku Dashboard causes express-stormpath to not find the apiKey and secret fields (even if you export variables).

Customize appsetings.json for user in ASP Core 1 app

My goal is to have appsettings.json file with production configurations and have possibility to costomize it for every developer, e.g. use local connection strings. So it does not similar to transform web.config mechanism, i don't want depends on bulid configuration. Can anyone provide solution for this goal?
In one of my past project we do so: we store all configure information in custom config.xml and parsed it into the custom structure. Web.config contains only server configaration. every developer has own copy of config files with his own data. Solution is that application use configuration files from path, that specified in environment path in windows via Environment.GetEnvironmentVariable("key").
Does anyone have idea better than my one?
This is how I manage configuration: see comments in the code
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json"); // this one has default configuration
// this file name is added to my gitignore so it won't get committed,
// I keep local dev configuration there
builder.AddJsonFile("appsettings.local.overrides.json", optional: true);
if (env.IsDevelopment())
{
// This reads the configuration keys from the secret store.
// if you need a more secure place for dev configuration use usersecrets
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
builder.AddUserSecrets();
}
// the order in which config sources is added is important, a source added later
// will override the same settings from a source added before
// environment variables is usually for production and therefore added last to give it higher priority
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}

Resources