Hi, seems we have a PR related to this issue, Enable Login with this tenant for templates contains microservice-template label. please guide me using that PR if possible.
NO, I shared my code as you asked, and already added this.
Do I need to config AuthServer:Authority in authServer too? After clicking on Login
I see redirect to auth.domain.com
which is host's issuer and then redirected to host home page.
the url after click on login:
https://auth.tonner.io/connect/authorize?client_id=Web&redirect_uri=https%3A%2F%2Fapp.tonner.io%2Fsignin-oidc&response_type=code%20id_token&scope=<scopes>&response_mode=form_post&nonce=<nonce>&access_token=<token>&tenantid=bec78466-c1c3-d8dc-beb3-3a112a214a25&tenantusername=admin&returnurl=https%3A%2F%2Fapp.tonner.io%2FSaas%2FHost%2FTenants&state=<state>&x-client-SKU=ID_NET8_0&x-client-ver=7.0.3.0
is it possible to impersonate tenant on the host domain? If yes, please guide me!
Hi,
How do you configure the subdomain tenant resolver?
Could you share your steps?
in web
, web.public
& authserver
I added:
Configure<AbpTenantResolveOptions>(options =>
{
options.AddDomainTenantResolver(configuration["TenantDomain"]);
});
also this config in their appSettings:
"TenantDomain": "https://{0}.app.domain.com"
...
"TenantDomain": "https://{0}.pub.domain.com"
...
"TenantDomain": "https://{0}.auth.domain.com"
in authserver
module:
PreConfigure<AbpOpenIddictWildcardDomainOptions>(options =>
{
options.EnableWildcardDomainSupport = true;
options.WildcardDomainsFormat.Add(configuration["WildCardDomains:AuthServer"]);
options.WildcardDomainsFormat.Add(configuration["WildCardDomains:Web"]);
options.WildcardDomainsFormat.Add(configuration["WildCardDomains:PublicWeb"]);
});
and authserver's appSettings:
"WildCardDomains": {
"AuthServer": "https://{0}.auth.domain.com",
"Web": "https://{0}.app.domain.com",
"PublicWeb": "https://{0}.pub.domain.com"
}
then in web
& web.public
:
if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"]))
{
context.Services.Configure<OpenIdConnectOptions>(
"oidc", options =>
{
options.MetadataAddress = configuration["AuthServer:MetaAddress"]!.EnsureEndsWith('/') +
".well-known/openid-configuration";
var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider;
options.Events.OnRedirectToIdentityProvider = async ctx =>
{
ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"]!.EnsureEndsWith('/') + "connect/authorize";
var currentTenant = ctx.HttpContext.RequestServices.GetRequiredService<ICurrentTenant>();
var tenantDomain = configuration["TenantDomain"];
if (currentTenant.IsAvailable && !string.IsNullOrEmpty(tenantDomain))
{
ctx.ProtocolMessage.IssuerAddress =
ctx.ProtocolMessage.IssuerAddress.Replace("{0}", $"{currentTenant.Name}");
}
else
{
ctx.ProtocolMessage.IssuerAddress =
ctx.ProtocolMessage.IssuerAddress.Replace("{0}.", string.Empty);
}
if (previousOnRedirectToIdentityProvider != null)
{
await previousOnRedirectToIdentityProvider(ctx);
}
};
var previousOnRedirectToIdentityProviderForSignOut =
options.Events.OnRedirectToIdentityProviderForSignOut;
options.Events.OnRedirectToIdentityProviderForSignOut = async ctx =>
{
// Intercept the redirection for signout so the browser navigates to the right URL in your host
ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"]!.EnsureEndsWith('/') +
"connect/logout";
var currentTenant = ctx.HttpContext.RequestServices.GetRequiredService<ICurrentTenant>();
var tenantDomain = configuration["TenantDomain"];
if (currentTenant.IsAvailable &&
!string.IsNullOrEmpty(tenantDomain))
{
ctx.ProtocolMessage.IssuerAddress =
ctx.ProtocolMessage.IssuerAddress.Replace("{0}", $"{currentTenant.Name}");
}
else
{
ctx.ProtocolMessage.IssuerAddress =
ctx.ProtocolMessage.IssuerAddress.Replace("{0}.", string.Empty);
}
if (previousOnRedirectToIdentityProviderForSignOut != null)
{
await previousOnRedirectToIdentityProviderForSignOut(ctx);
}
};
}
);
}
and the userMenu in web
& web.public
var authServerUrl = _configuration["AuthServer:Authority"] ?? "~";
var returnUrl = _configuration["App:SelfUrl"] ?? "";
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
var tenantDomain = _configuration["TenantDomain"];
if (currentTenant.IsAvailable && !string.IsNullOrEmpty(tenantDomain))
{
authServerUrl = authServerUrl.Replace("{0}", $"{currentTenant.Name}");
returnUrl = tenantDomain.Replace("{0}", $"{currentTenant.Name}");
}
else
{
authServerUrl = authServerUrl.Replace("{0}.", string.Empty);
}
I kept gateways and services as before except openIddict data seeder.
Hi, I added subdomain tenant resolver to my abp application. everything works except "login as this tenant" and user menus "Security Log" & "My Account" has invalid url (actually I fixed it with {0}
replacer).
When I trying to impersonate tenant from host dashboard it's just redirect to the host home page. I think this is related to the tenant resolver. I expected it to impersonate the tenant on the host domain. Do we have a list of resolvers? Can we fix this by resolvers ordering?
hi
is it best practice to add whole process inside custom grant type?
I tend to do this.
then the token and refresh token are accessible at /connect/token?
Yes, Because your
access_token
is legal.You can add some simple logic checks in your custom grant type. and then integrate Telegram.
Thank you very much sir. You gave me a very clear idea. I decided to implement user creator in a separate service. First, I will search for the identityUser via loginInfo by the provider infos, if it is not found, I will reject the request in custom grant type. Then I check the response in the client side, if the request is rejected, I'll send a request with telegram user's info to the semi-fake user creator service.
Thank you @maliming. You are awesome. is it best practice to add whole process inside custom grant type?
I have a host-side entity to store keys for hash decryption: key = $"{ICurrrentTenant.Name}:{TelegramBotApiToken}"
. tenant name is same as bot username.
here are steps I need to do to grant a request:
then the token and refresh token are accessible at /connect/token
?
So far, the framework's identity module has met all the infrastructure I needed, and I never had to customize it. I have no idea where to start. I'm not asking you for code, I just want to know where I should go to customize ABP authentication for this or any similar scenarios. I appreciate your guidance.
Best regards.