ASP.NET Core Identity Implementation using Cassandra Database - cassandra

I am building an ASP.NET Core MVC application using the Cassandra Database on Windows.
I need help implementing ASP.NET Core Identity with Cassandra.
On Google I found AspNet.Identity.Cassandra in the version 2.0.0.1, but it's not compatible with ASP.NET Core 1.0.

I'm working on data store adapter for ASP.NET Core Identity
which allows you to build ASP.NET Core web applications, including membership, login, and user data. With this library, you can store your user's membership related data on Apache Cassandra.
Please note the library is in alpha version and needs to be finished
If you want to try it, follow these steps:
1 - Run the following command from the package manager console to install Cassandra identity provider.
Install-Package AspNetCore.Identity.Cassandra -Version 1.0.0-alpha1
2 - Add settings to appsettings.json
{
"CassandraNodes": [
"127.0.0.1"
],
"CassandraOptions": {
"KeyspaceName": "identity",
"Replication": {
"class": "NetworkTopologyStrategy",
"datacenter1": "1"
}
}
}
3 - Configure services in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// CassandraOptions configuration
services.Configure<CassandraOptions>(Configuration.GetSection("CassandraOptions"));
// Cassandra ISession initialization
services.AddCassandraSession<Cassandra.ISession>(() =>
{
var cluster = Cassandra.Cluster.Builder()
.AddContactPoints(Configuration.GetSection("CassandraNodes").GetChildren().Select(x => x.Value))
.Build();
var session = cluster.Connect();
return session;
});
// Added custom Cassandra stores
services.AddIdentity<ApplicationUser, ApplicationRole>()
.UseCassandraStores<Cassandra.ISession>()
.AddDefaultTokenProviders();
// Other code omitted
}
4 - And finally initialize DB in Program.cs
public static class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.InitializeIdentityDb<ApplicationUser, ApplicationRole>();
}
For more information check project site at github.

Few Option
Try implement your own cassandra identity for ASP.net core, there is many sample how to create your Custom IdentityUser for ASP.net (using Google) then make it work with Cassandra
Fork / Update the AspNet.Identity.Cassandra project to .net core (open source, so makes easy to implement your own)
Use another provider, instead of Cassandra Database
Request update on github (link on section 2.)

Related

I have to integrate ServiceStack together with Kephas. How do I make them both play together with Dependency Injection?

ServiceStack uses a dialect of Funq (no support for metadata), where Kephas uses one of MEF/Autofac (requires metadata support). My question has two parts:
How to make ServiceStack and Kephas use one DI container, if this is possible?
Depending on the answer above: how to make ServiceStack services (like IClientCache) available to Kephas components, knowing that such services may not be annotated with [AppServiceContract]?
You can make ASP.NET and Kephas use one container by choosing to work with Autofac. However, as #mythz pointed out, you will need to provide the Autofac IoC Adapter to the ServiceStack. I don't think you will have any problems with ASP.NET in doing so, as Autofac is the first recommendation of the ASP.NET Core team.
For ASP.NET Core, reference the Kephas.AspNetCore package and inherit from the StartupBase class if you need to be all setup. However, if you need to be in control, have a look at https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs and write your own Startup class. Another resource that you might find useful is the Kephas.ServiceStack integration package.
Then, additionally to annotating service contracts and service implementations, Kephas allows you to provide service definitions by implementing the IAppServiceInfoProvider interface. These classes are automatically discovered, so this is pretty much everything you have to do.
public class ServiceStackAppServiceInfoProvider : IAppServiceInfoProvider
{
public IEnumerable<(Type contractType, IAppServiceInfo appServiceInfo)> GetAppServiceInfos(IList<Type> candidateTypes, ICompositionRegistrationContext registrationContext)
{
yield return (typeof(IUserAuthRepository),
new AppServiceInfo(
typeof(IUserAuthRepository),
AppServiceLifetime.Singleton));
yield return (typeof(ICacheClient),
new AppServiceInfo(
typeof(ICacheClient),
ctx => new MemoryCacheClient(),
AppServiceLifetime.Singleton));
}
}
Note in the above example that for IUserAuthRepository there is no implementation provided. This indicates Kephas to auto-discover the implementation in the types registered for composition. Alternatively, feel free to use an instance or a factory in the registration, if you need to be deterministic.
I've never heard of Kephas before, but if you're referring to this Kephas Framework on GitHub it says it uses ASP.NET Core in which case it's best if you get them to both use ASP.NET Core's IOC which you can do by either registering your dependencies in ConfigureServices in your App's Startup:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...
}
}
Or alternatively in ServiceStack's latest v5.6 release for Modular Startup change your ASP.NET Core Startup class to inherit from ModularStartup, e.g:
public class Startup : ModularStartup
{
public Startup(IConfiguration configuration) : base(configuration){}
public new void ConfigureServices(IServiceCollection services)
{
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
}
}
In which case you'll be able to Register ASP.NET Core dependencies in AppHost by registering them in your AppHost's Configure(IServiceCollection) where they can be resolved through both ASP.NET Core's IOC + ServiceStack's IOC, e.g:
public class AppHost : AppHostBase
{
public override void Configure(IServiceCollection services)
{
services.AddSingleton<IRedisClientsManager>(
new RedisManagerPool(Configuration.GetConnectionString("redis")));
}
public override void Configure(Container container)
{
var redisManager = container.Resolve<IRedisClientsManager>();
//...
}
}

Application Insights to azure webjob .Net Core 2.0

How to add application insights telemetry (Application Insights) to azure webjob ?
With recently released WebJob SDK 3.0, you can add ApplicationInsights in the ConfigureLogging method
public static async Task Main(string[] args)
{
var builder = new HostBuilder()
.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices().AddAzureStorage();
})
.ConfigureAppConfiguration(b =>
{
// Adding command line as a configuration source
b.AddCommandLine(args);
})
.ConfigureLogging((context, b) =>
{
b.SetMinimumLevel(LogLevel.Debug);
b.AddConsole();
// If this key exists in any config, use it to enable App Insights
string appInsightsKey = context.Configuration["ApplicationInsights:InstrumentationKey"];
if (!string.IsNullOrEmpty(appInsightsKey))
{
b.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
}
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
You can add AI to Web Jobs during the development time as a Nuget Package.
AI .NET Core Nuget is here. Package name is a bit misleading (Microsoft.ApplicationInsights.AspNetCore) but it's supposed to work with all .Net core apps.
AI .NET Core GitHub page is here (with some customization options explained in Wiki).
Getting started guide is on GitHub and learn.microsoft.com as well. It's a bit lengthy guide, so I hope links are OK (although not in full accordance with SO guidelines) and I won't need to post it as part of the reply.

NLog Custom Target fails in Azure .NET Core 2.1

I've been using NLog with .NET Core 2.0 and a custom target to write to Azure Blob storage successfully for a while.
I've now upgraded to .NET Core 2.1 and the deployed solution to an Azure Web App fails because, according to the Kudu Event Log, NLog cannot find the custom target defined in the NLog config file, although it appears to work just fine locally.
My host builder is as follows:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUnityServiceProvider()
.UseNLog()
.UseStartup<Startup>();
and my NLog target is defined in the startup class:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
.AddJsonFile("appsettings.local.json", true)
.AddEnvironmentVariables();
Configuration = builder.Build();
HostingEnvironment = env;
NLogRegistry.Register(env, new ConfigurationAdapter(Configuration));
}
The NLog Registry is just a wrapper for a solution based on Custom target with injected services for NLog with .net core
i.e.
public class NLogRegistry
{
public static void Register(IHostingEnvironment env, IConfigurationAdapter configuration)
{
//Setup custom NLog Azure Blob logger with injected configuration
Target.Register<AzureBlobStorageTarget>("AzureBlobStorage");
var nlog = ConfigurationItemFactory.Default.CreateInstance;
ConfigurationItemFactory.Default.CreateInstance = type =>
{
try
{
return nlog(type);
}
catch (Exception)
{
}
return new AzureBlobStorageTarget(configuration);
};
env.ConfigureNLog("nlog.config");
}
}
What I think is happening is that there is some change of behavior to the .NET Core pipeline so that NLog is being invoked before the Startup method. As NLog is configured to "auto-discovery" nlog.config, it tries to set up before I've had chance to configure the target correctly.
If I rename the nlog.config file then the auto-discovery doesn't happen and NLog has to wait until I've run the ConfigureNLog method in my register class. Then, everything works fine.
Does anyone know what the correct place in the ASP.NET Core 2.1 pipeline invoked by Azure is to ensure that I can configure the NLog target correctly before NLog tries to autoconfigure itself?
Instead of injecting IConfiguration in constructor to your AzureBlobStorageTarget, then you can now just use NLog Layout-Type for the AzureBlobStorageTarget-properties.
Then configure the Layout with ${configsetting} introduced with NLog.Extension.Logging ver. 1.4.0:
https://github.com/NLog/NLog/wiki/ConfigSetting-Layout-Renderer
Maybe also consider changing to this NLog-target instead:
https://github.com/JDetmar/NLog.Extensions.AzureStorage#blob-configuration
But if you insist on using custom target that relies on dependency injection of constructor parameters:
https://github.com/NLog/NLog/wiki/Dependency-injection-with-NLog

Owin startup bug with Umbraco Cloud - netStandard reference missing

In our current Umbraco Cloud project, we are using the Hangfire library (1.6.17) - the lib has a OWIN dependency (1.0.0).
Here is the code to call the hangfire launch:
In our current project, we are using the Hangfire library (1.6.17) - the lib has a OWIN dependency (1.0.0).
Here is the code to call the hangfire launch:
using Microsoft.Owin;
using Owin;
using Umbraco.Web;
using Hangfire;
using Hangfire.Dashboard;
using Hangfire.Annotations;
using Umbraco.Core.Models;
using Umbraco.Core;
using System.Web;
[assembly: OwinStartup(typeof(XX.Web.Core.Startup))]
namespace XX.Web.Core
{
public class Startup : UmbracoDefaultOwinStartup
{
public override void Configuration(IAppBuilder app)
{
//ensure the default options are configured
base.Configuration(app);
var cs = Umbraco.Core.ApplicationContext.Current.DatabaseContext.ConnectionString;
GlobalConfiguration.Configuration.UseSqlServerStorage(cs);
app.UseHangfireDashboard("/umbraco/backoffice/hangfire", new DashboardOptions
{
Authorization = new[] { new UmbracoUserAuthorisedFilter() },
AppPath = "/Umbraco"
});
app.UseHangfireServer();
}
}
public class UmbracoUserAuthorisedFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
// In case you need an OWIN context, use the next line,
// `OwinContext` class is the part of the `Microsoft.Owin` package.
//var context = new OwinContext(owinEnvironment);
// Allow all authenticated users to see the Dashboard (potentially dangerous).
//return context.Authentication.User.Identity.IsAuthenticated;
//this if you want to lock down to admins only
var userService = ApplicationContext.Current.Services.UserService;
var user = userService.GetByUsername(HttpContext.Current.User.Identity.Name);
return user.IsAdmin();
//this if you just want to make sure user is logged into backoffice
//return UmbracoContext.Current.Security.CurrentUser != null;
}
}
}
This is the default hangfire startup code to be able to use the library. The code has been working fine on 2 local machines, one Azure Web App instance but when I push this code to the Umbraco Cloud branch I get the following error:
Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
The issue is: we are not using .net standard, both projects (web and core) are using .net framework 4.6.2
Is there any workaround for that issue ?

ASP.NET Core Directory.EnumerateDirectories not working when deployed to Azure AppService

I am currently experimenting with ASP.NET Core MVC by creating a simple blog with static views. I've created a custom class that implements the IViewLocationExpander in order to enumerate a directory structure to retrieve razor views
public class FolderEnumerationViewExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
IEnumerable<string> viewLocations)
{
var locations = viewLocations.ToList();
foreach (var directory in Directory.EnumerateDirectories("Views/Blog", "*", SearchOption.AllDirectories))
{
locations.Add($"/{directory.Replace("\\","/")}" + "/{0}.cshtml");
}
return locations.AsEnumerable();
}
}
I've configured this class to be used within Startup.cs's ConfigureServices method
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IPostsMetaDataRepositry>(new JsonPostsMetaDataRepository(ConfigurationPath.Combine("posts.json")));
services.Configure<RazorViewEngineOptions>(o => { o.ViewLocationExpanders.Add(new FolderEnumerationViewExpander()); });
services.AddMvc();
}
This seems to work perfectly when I run my application locally using IISExpress however, when I deploy the application to an Azure AppService, only a handful of the directories within ~/Views/Blog are being enumerated when trying to locate views.
I'm fairly certain the issue is one of configuration but I am having a difficult time tracking down what it could be. Any ideas as to why this may be occurring?
I have the full source of this project on GitHub for reference: https://github.com/pstricker/Develothink

Resources