Using Custom Environments in ASP.NET Core - visual-studio-2017

My appsettings files does work I see them being used according to which launching profile I use however my localhost profile doesn't work because it doesn't seems to exist in the actual Framework I use. Is there anyway to add a custom one such as "localhost"?
Edit :
Thanks!

In your Program.cs, add a call to config.AddJsonFile():
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("appsettings.Localhost.json", optional: true);
})
.UseStartup<Startup>();

Related

How to send the contents of a file downloaded from aws s3 using apache camel in json format?

I have a rest api using apache camel. When I hit a post request on a route, it gets a file from S3. Here is the code for that ->
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.route()
.setHeader(AWS2S3Constants.KEY, constant("filename"))
.to("aws2-s3://bucketname?accessKey=INSERT&secretKey=INSERT&region=INSERT&operation=getObject")
.endRest();
}
}
This gives the content of the file in Postman. I want the response in a json format where the contents of the file will be in the content key of json. How to do this?
Make sure you have binding mode enabled (auto|json) in your REST configuration and the consumes/produces set on your route. Now write your processor to build your response object and set it in the body. Camel will handle the rest for you.
public static class HelloRoute extends RouteBuilder {
restConfiguration().component("netty-http").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.consumes("application/json").type(YourRequest.class)
.produces("application/json").outType(YourResponse.class)
.route()
.setHeader(AWS2S3Constants.KEY, constant("filename"))
.to("aws2-s3://bucketname?accessKey=INSERT&secretKey=INSERT&region=INSERT&operation=getObject")
//.process("responseBuilderProcessor")
.endRest();
}
}

Set the AWS S3 Key header in the URI only

I have a rest api using apache camel. When I hit a post request on a route, it should get a file from S3. I am sending json data(filename, bucketName, accesskey, secretkey, region) in order to extract the file from s3. Here is the code for that ->
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.route()
.setHeader(AWS2S3Constants.KEY, constant("filename"))
.to("aws2-s3://bucketnameaccessKey=INSERT&secretKey=INSERT&region=INSERT&operation=getObject")
.to("file:/tmp/")
The issue is that I don't want the .setHeader(AWS2S3Constants.KEY, constant("filename"))
part. Is there a way to remove that and put an alternate to that in the URI itself. I tried something like this ->
public static class HelloRoute extends RouteBuilder {
#Override
public void configure() {
rest("/")
.post("file-from-s3")
.route()
.to("aws2-s3://bucketnameaccessKey=INSERT&secretKey=INSERT&region=INSERT&filename=hello.txt&operation=getObject")
.to("file:/tmp/")
But this is giving me an error java.lang.IllegalArgumentException: AWS S3 Key header missing.. Is there some other way to do this?
Sometimes build an AWS Request can be complex, because of multiple options. We introduce the possibility to use a POJO as body.
Take a look at: https://camel.apache.org/components/latest/aws2-s3-component.html#_using_a_pojo_as_body

Is Xamarin Master-Detail Template Broken When used with Azure Backing?

The Master-Detail template in Xamarin has typically been a great starting point for many of my apps that work with .Net Core Backing Service. For review it has a Dependency service in the Client that allows Mocking of the Azure Backing Service or connection to a real or local service while in development.
The control variable generated by the template is public static bool UseMockDataStore = true;
All Code discussed is completely found here: https://github.com/BicycleMark/SignalRGB
I created a Xamarin Master-Detail project naming it SignalRGB and did the following:
The solution project structure looks like:
I start Instance one Visual Studio 2019 And Run SignalRGB.Web
3) Made Note of url: [https://localhost:44300]
4) Opened another Instance of Visual Studio (2) to run client with UseMockDataSource=false / The default it displayed results in Client using MockDataSource
5)went to these lines and updated Client for talking to my local server waiting for an http request :
public static string AzureBackendUrl =
//DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:44300";
DeviceInfo.Platform == DevicePlatform.Android ? "http://localhost:44300" : "http://localhost:44300";
public static bool UseMockDataStore = false;
public App()
{
InitializeComponent();
if (UseMockDataStore)
{
DependencyService.Register<MockDataStore>();
}
else
{
DependencyService.Register<AzureDataStore>();
}
MainPage = new MainPage();
}
Went and ran SignalRGB.UWP from VS Instance(2) and client application hung on the line GetStringAsync():
bool IsConnected => Connectivity.NetworkAccess == NetworkAccess.Internet;
public async Task<IEnumerable<Item>> GetItemsAsync(bool forceRefresh = false)
{
if (forceRefresh && IsConnected)
{
var json = await client.GetStringAsync ($"api/item");
items = await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<Item>>(json));
}
return items;
}
I have tried other platforms iOS and get same result:
What Am I doing wrong here?
Oversight? in the templated code perhaps. 44300 is the port but notice the protocol.
DeviceInfo.Platform == DevicePlatform.Android ? "https://localhost:44300" :

InvalidOperationException: Scheme already exists: Bearer

I recently resumed work on a project that had lain dormant for a year. It was using Angular on AspNet Core 1.1 and using an early version of OpenIddict 1.0. It was developed using VS2017.
I updated VS2017 to the latest release (15.7.5) but the project would not compile and when I fixed the compilation errors it wouldn't run. So eventually I bit the bullet and decided to update the project to Asp Net Core 2.1 and to use the latest version of OpenIddict. I have the project so it compiles but when it starts it gives the error in the title, namely "InvalidOperationException: Scheme already exists: Bearer"
I can't see what is wrong. I understand that somewhere a second scheme named 'Bearer' is being added, but I can't figure out where. I am enclosing below my Startup.cs in its entirety.
using AspNet.Security.OpenIdConnect.Primitives;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SIAngular.DBContexts;
using SIAngular.Models;
using SIAngular.Services;
using OpenIddict.Abstractions;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace SIAngular
{
public class Startup
{
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc();
services.AddDbContext<ApplicationDbContext>(options =>
{
// Configure the context to use Microsoft SQL Server.
options.UseSqlServer(Configuration.GetConnectionString("SqlConnection"));
// Register the entity sets needed by OpenIddict.
// Note: use the generic overload if you need
// to replace the default OpenIddict entities.
options.UseOpenIddict();
});
// Register the Identity services.
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
//.AddDefaultTokenProviders();
// Configure Identity to use the same JWT claims as OpenIddict instead
// of the legacy WS-Federation claims it uses by default (ClaimTypes),
// which saves you from doing the mapping in your authorization controller.
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
services.AddOpenIddict()
// Register the OpenIddict core services.
.AddCore(options =>
{
// Configure OpenIddict to use the Entity Framework Core stores and models.
options.UseEntityFrameworkCore()
.UseDbContext<ApplicationDbContext>();
})
// Register the OpenIddict server services.
.AddServer(options =>
{
// Register the ASP.NET Core MVC services used by OpenIddict.
// Note: if you don't call this method, you won't be able to
// bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
options.UseMvc();
// Enable the token endpoint.
options .EnableTokenEndpoint("/connect/token");
options.AcceptAnonymousClients();
options.DisableScopeValidation();
// Note: the Mvc.Client sample only uses the code flow and the password flow, but you
// can enable the other flows if you need to support implicit or client credentials.
options.AllowPasswordFlow();
// Mark the "email", "profile" and "roles" scopes as supported scopes.
options.RegisterScopes(OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Profile,
OpenIddictConstants.Scopes.Roles);
// During development, you can disable the HTTPS requirement.
options.DisableHttpsRequirement();
// Note: to use JWT access tokens instead of the default
// encrypted format, the following lines are required:
//
options.UseJsonWebTokens();
options.AddEphemeralSigningKey();
})
// Register the OpenIddict validation services.
.AddValidation();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = "http://localhost:53244/";
options.Audience = "resource_server";
options.RequireHttpsMetadata = false;
//options.IncludeErrorDetails = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = OpenIdConnectConstants.Claims.Subject,
RoleClaimType = OpenIdConnectConstants.Claims.Role
};
});
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
app.UseAuthentication();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
}
}
Can someone please exp-lain what I am doing wrong. My intent was to follow the OpenIddict examples but clearly I went wrong somewhere.
The full stacktrace follows:
System.InvalidOperationException: Scheme already exists: Bearer
at Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(String name, Action`1 configureBuilder)
at Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0`2.<AddSchemeHelper>b__0(AuthenticationOptions o)
at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options, IDictionary`2 schemes)
at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.<UseMiddleware>b__0(RequestDelegate next)
at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at SIAngular.Program.Main(String[] args) in C:\Users\username\Documents\Visual Studio 2017\Projects\SIAngular\Program.cs:line 20
I finally found the answer which is probably obvious to OpenIddict experts, but not to casual users.
Since I am using JWT the.AddValidation() after the registration of the OpenIddict server options is not needed. This is obvious in hindsight but I hope this helps someone else with this problem. I am sure I am not thbe only person dumb enough to have been caught by this and when I look at OpenIddict samples now I understand, but I think the comment "For JWT tokens, use the Microsoft JWT bearer handler." could be amended to "For JWT tokens, use the Microsoft JWT bearer handler and remove the call to AddValidation below.
I have tried the below code and worked for me.
public void ConfigureServices(IServiceCollection services)
{
// Code omitted for brevity
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Audience = "https://localhost:5000/";
options.Authority = "https://localhost:5000/identity/";
})
.AddJwtBearer("AzureAD", options =>
{
options.Audience = "https://localhost:5000/";
options.Authority = "https://login.microsoftonline.com/eb971100-6f99-4bdc-8611-
1bc8edd7f436/";
});
}
You can read this complete document on the below URL:
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-6.0
I have tried other solution as well.
Please check if you have multiple startup.cs files and you are using any authentication schemes in that files.
and also check to publish folder/deployment folder, need to delete App_Data Folder before deploying fresh/ latest changes.

Accessing Session in HttpRequest Pipelines

I'm trying to access a query string parameter and save it to a Session variable. Since the solution I'm working on has several base layouts, the simplest approach would be to add this to a pipeline handler. However, my code is failing because args.Context.Session is null:
public class SaveQueryStringToSession : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull((object)args, "args");
string queryString = WebUtil.GetQueryString("parm1");
if (queryString.Length <= 0)
return;
args.Context.Session["parm1"] = queryString;
}
}
This occurs when this method is inserted into either the HttpRequestBegin or HttpRequestEnd pipeline. Curious to know why, and if there is a standard workaround or pattern to use here. (Yes, I will add a null check. No need to point that out.)
I'm running Sitecore Sitecore.NET 6.4.1 (rev. 110720) on IIS 7.5 (Integrated .Net 2.0)
Possibly relevant links:
What is the first global.asax event that Session is accessible assuming the context handler is IRequiresSessionState or IReadOnlySessionState?
http://intothecore.cassidy.dk/2009/02/session-state-and-integrated-pipeline.html
The HttpRequestBegin pipeline is wired up to the HttpApplication.BeginRequest event, and this event is fired before the HttpSession object has been instantiated. Using the HttpRequestEnd pipeline does not work because the HttpSession object has already been disposed by the time the HttpApplication.EndRequest event is fired.
The session becomes available after the PostAcquireRequestState event is fired. To intercept this, create a class that implements IHttpModule, and add it to the <httpModules> element in Web.config. The HttpModule code will need to check if the request requires session state, as attempting to read the session for a static resource request will throw an exception.
Here is HttpModule code that accesses the Session and QueryString:
public class MyHttpModule :IHttpModule
{
public void Init(HttpApplication context)
{
context.PostAcquireRequestState += RequestHandler;
}
public void Dispose()
{
//
}
public void RequestHandler(object sender, EventArgs e)
{
var app = (HttpApplication) sender;
if (app.Context.Handler is IRequiresSessionState)
{
var session = app.Session;
var queryString = app.Request.QueryString["test"];
session["test"] = queryString;
}
}
}
It is worth noting that Sitecore's HttpRequestBegin and HttpRequestEnd pipelines are wired to ASP.NET via an HttpModule:
<add type="Sitecore.Nexus.Web.HttpModule,Sitecore.Nexus"
name="SitecoreHttpModule" />
Thanks to #ddysart for pointing me in the right direction, and to this answer for the correct event to listen for.
Actually instead of httpRequestBegin or HttpRequestEnd you can use httpRequestProcessed during which sitecore process the HttpRequest so you can access the Session.
You will be able to use the same code you have provided earlier.
public class SaveQueryStringToSession : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull((object)args, "args");
string queryString = WebUtil.GetQueryString("parm1");
if (queryString.Length <= 0)
return;
args.Context.Session["parm1"] = queryString;
}
}