Configure IdentityServer4 ConfigurationStore and OperationalStore in a Multi-Tenant Environment - identityserver4

We have a web API that used IdentityServer4 for authentication. I am trying to change the authentication service to support multi-tenancy by keeping existing DBs. So there are separate DB for each tenant.
I am currently struggling to configure ConfigurationStore and OperationalStore.
Option 01: Since we have separate DB for each tenant, ConfigurationDb and PersistedGrantDb related tables can be added to those DBs.
Option 02: Use common DB to keep ConfigurationDb and PersistedGrantDb related tables.
What would be the best approach?
services.AddIdentityServer()
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30; // interval in seconds
});

We couldn't find a way to configure ConfigurationStore and OperationalStore in separate DBs. Since that we have configured them in our common DB. So final DB structure is like following.
TenantDB: Common DB to all the tenants. Holds tenant configurations
like tenant name, host/domain details, connection strings. And
ConfigurationStore and OperationalStore configurations.
Tenant01DB : Tenant 01 Data
Tenant02DB : Tenant 02 Data
Tenant03DB : Tenant 03 Data

Related

Unable to find a management group - terraform

Any advice on additional troubleshooting steps for the below error?
Error: Management Group "00000000-0000-0000-0000-000000000000" was not found
with data.azurerm_management_group.current
on main.tf line 40, in data "azurerm_management_group" "current":
data "azurerm_management_group" "current" {
I am using a service principal with the Contributor role assigned to authenticate to azure.
I have ensured the management group UUID set in the terraform config points to the correct ID.
I have ensured that access management for Azure resources in the azure active directory is enabled so that my user account can manage access to all Azure subscriptions and management groups in this tenant.
I know that the GET Management REST API throws errors when calls are made to azure ad tenants with large resource hierarchies that would return a payload greater than 15 MB. However, I only have 1 root tenant management group in my tenant that I want to reference.
The data source is configured as:
data "azurerm_management_group" "current" {
# parent management group ID pulled in as a variable from terraform cloud using interpolation
name = var.parent_mg_id
}
The management group resource which will be created once the data source can be referenced is currently set as follows:
resource "azurerm_management_group" "az104-02-mg1" {
display_name = "az104-02-mg1"
# current subscription associated with existing tenant assigned to this management group
subscription_ids = [data.azurerm_subscription.current.subscription_id]
# existing root management group within AAD tenant set as parent mg of az-104 lab 2 management group
parent_management_group_id = data.azurerm_management_group.current.parent_management_group_id
}
Thanks in advance!
I tried to reproduce the same issue in my environment and got the below results
I have used the following script for the management groups it worked for me
vi vm.tf
provider "azurerm" {
features {}
}
data "azurerm_subscription" "current" {
}
resource "azurerm_management_group" "example_parent" {
display_name = "ParentGroup"
subscription_ids = [
data.azurerm_subscription.current.subscription_id,
]
}
resource "azurerm_management_group" "example_child" {
display_name = "ChildGroup"
parent_management_group_id = azurerm_management_group.example_parent.id
subscription_ids = [
data.azurerm_subscription.current.subscription_id,
]
}
Follow the below steps to execute the file
Terraform init
It will initialize the file
terraform plan
This will creates an execution plan and it will preview the changes that terraform plans to make the infrastructure
terraform apply
This will creates or updates the infrastructure depending on the configuration

Azure AD and Core Idenity Roles Hybrid

Is it possible to use Azure AD and Core Identity Roles together? Basically the user will log into the App using AD, which I have that done already. But as they use the app, thier roles will be based on the AspNetRoles and AspNetUsersRoles tables. I was thinking that I would have to use the ClaimsPrincipal factory to extend the claims object that is created when the user logs in.
By using the ASP.NET identity you can manage the user locally in your database, and user Azure AD as external identity provider which enable the AAD accounts to login in your application. You can identify the user and link it to the user in your local database. You can then also manage the roles with your local users and Azure AD users.
Read more here.
Create a new application with Individual User Accounts.
Install this package : Microsoft.AspNetCore.Authentication.AzureAD.UI
services.AddDbContext(options => options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity() .AddEntityFrameworkStores();
services.AddAuthentication(sharedOptions => }).AddAzureAD(options =>
Configuration.Bind("AzureAd", options)).AddCookie();
Update appsettings.json "AzureAd": { "Instance": "https://login.microsoftonline.com/",
"Domain": "xxx.onmicrosoft.com", "TenantId": "xxxxxx-xxxxx-4f08-b544-b1eb456f228d",
"ClientId": "xxxxx-xxxxx-4717-9821-e4f718fbece4", "CallbackPath": "/signin-oidc",
"CookieSchemeName": "Identity.External" },
It depends on the user to choose login with local authentication or Azure AD Authentication.

How do I authenticate QuestDb with database users

I'm considering using QuestDb for a small hobby project but I can't seem to wrap my head around how authentication is dealt with in QuestDb. I peeked at the Enterprise page and it almost looks like authentication is only available to enterprises.
The docs shows authentication for the Influxdb Line Protocol but nothing that resembles for example mysql and its database users.
How do I create database users and lock down QuestDb to only be used with the authenticated users/users with correct permissions?
Authentication over InfluxDB line protocol was added as a feature request for this protocol only and ensures only that clients writing to QuestDB are authenticated before being allowed to send records to tables.
For authenticating over Postgres wire, there is the equivalent of host-based authentication, i.e. in Node.js this looks like:
const { Client } = require("pg")
const start = async () => {
const client = new Client({
database: "qdb",
host: "127.0.0.1",
password: "quest",
port: 8812,
user: "admin",
})
await client.connect()
console.log("Connected")
}
start()
Only one database and one admin user is supported at the moment and you should keep in mind that anyone who can connect to the host using these credentials has database access and can read/write to tables on this host.
If you want to ensure your installation is locked down, you should at a minimum change the default connection credentials specified in the server configuration file (server.conf) such as changing the default username and password, and only enable the protocol(s) that you are reading and writing with.
Depending on where the installation is deployed, you could take steps beyond the QuestDB config itself and whitelist incoming / outgoing network connections (on EC2 for instance) to only allow connections coming from a specific IP, or within a VPC, for example.
If having multiple database users with role-based access is something you really need, feel free to open an issue with a feature request.
edit: It might be worth noting that you can also set the HTTP server to readonly mode which was discussed in another stackoverflow question

Passing IIS Basic Authentication to SQL Server in .NET Core 2.1

A little background for this question:
I've got an ASP.NET Intranet application that accesses sensitive data in an MS SQL Server database. Because of the nature of the data, the database table itself is locked down to only select users. We're using Basic Authentication in IIS and impersonation in order to use integrated security when accessing the data.
All of that works fine, but we're now in the process of converting our Intranet site to .NET Core. I understand that impersonation of the sort we're using isn't directly supported in Core, but are there any options or workarounds available that would make this work?
There are two options for you:
Try WindowsIdentity.RunImpersonated which will use the current user identity to login to sql server.
public IActionResult About()
{
IList<Blog> blogs = new List<Blog>();
var user = (WindowsIdentity)User.Identity;
WindowsIdentity.RunImpersonated(user.AccessToken, () =>
{
var impersonatedUser = WindowsIdentity.GetCurrent();
blogs = _context.Blogs.ToList();
});
return Ok(blogs);
//_context
//ViewData["Message"] = "Your application description page.";
//return View();
}
You could run the .net core project under the user account in iis which has permission to access sql server, then check the user identity to see whether he has permission to access the sql server dynamically before he access the controller which will call db action method.

GoLang multi-tenant application database connections

I am new to golang and currently trying to build a multi-tenant application. In my application each tenants have their own database. My requirement is that I need to switch database connection per tenant request, how can this be accomplished in golang. I prefer postgresql for this project.
I can have a map of database connection to tenant, but not sure if this is a good practice.
Your help and suggestion is highly appreciated
I've handled a similar kind of requirement in Rails. Probably you can use the same approach in go-lang also.
I will have one master DB, which will hold just the tenant information. Like tenant name and db_name.
And I've got a rack middleware which will switch DB based on a subdomain(I'm using the subdomain to identify the tenant).
For example, Your master DB can have table tenants and an example record might probably look like this:
{
id: 1,
name: 'XYZ',
db_name: 'xyz'
}
and when your application receives a request with subdomain xyz, Your middleware should switch to xyz DB.
its a better solutions to create an schema instead of an entire database and on each request change the schema of the request identifying the tenant.other solutions is to create a database and reopen a connection on each request after the tenant recognition on the middleware

Resources