We want to work with some service inside AutoMapper profile. Below is just the idea which does not work. Please suggest how to implement such DI:
private void ConfigureAutoMapper(ServiceConfigurationContext context)
{
context.Services.AddSingleton(provider => new AutoMapper.MapperConfiguration(cfg =>
{
//TODO: implement
cfg.AddProfile(new CentralToolsApplicationAutoMapperProfile
(
provider.GetService<IBlobContainer<FileContainer>>()
));
}).CreateMapper());
}
public class CentralToolsApplicationAutoMapperProfile : AutoMapper.Profile
{
//TODO: implement
public CentralToolsApplicationAutoMapperProfile()
{
CreateMap(...);
CreateMap(...);
}
}
public class MyCustomUserMapper : IObjectMapper<User, UserDto>, ITransientDependency
approach seems not to be useful for our case.
Thank you. I will give it a try later on, because requirements have changed. Could you please explain why I cannot reopen another ticket (which I closed) or add answer? When I'm trying to do that, I receive the message saying I am not authorized to do that (I AM logged in).
OK. We implemented service on Angular side and seems like everything works now.
Good, but from ABP-based project's prospective, does it need to be something like this in front-end part: Angular Refresh Token implementation and from back-end part probably nothing needs to be added to make it work?
Hi, could you please make a short test example how to work with refresh_token? In current implementation (built from ABP template) we use only access_token.
Ok, thank you!
@maliming
we have managed to do that by our owns:
BACK-END: implemented & registered custom grant type validator in IdentityServer project:
SwitchToTenantGrantValidator : IdentityServer4.Validation.IExtensionGrantValidator
In short, ValidateAsync accepts the data of authenticated user (his access token, tenant ID, etc.) and makes the decision if the user has to be let in. The method writes data of target tenant into context result object;
FRONT-END: made a call to IdentityServer with the given custom grant type, supplying data required for (1). We used Angular, so I had to extend OAuthService package to support custom grant type request;
Still need to bring everything in order (if (2) was successful) to display correct data in UI: clean old states, etc. - since now old user is still displayed for some reason (despite dispatching new GetAppConfiguration);
The question that is still open: why you hardcoded custom grant type names? When we added manually some custom name to DB - it worked. But in ABP Identity Server management page we cannot do that.
Hi, we can see that meanwhile token lifetime is not prolonged per each request in UI, there is a fixed lifetime that is configured (1 year by default for now, as far as I remember). We want to provide a specific token life, like 15 mins and to prolong token lifetime per each request by this value. How would you recommend to do that?
Could you please make a test project demonstrating how to accomplish our goal? I've spent a lot of time searching for solution on stackoverflow, analyzing ABP code, etc. and I am far behind the schedule. But the solution is still not working.
The pieces of code I have ended up with are the following:
[Authorize]
public async Task<PagedResultDto<LookupDto<string>>> GetTenantsForCurrentUser()
{
if (!CurrentUser.IsAuthenticated)
return null;
var items = await _abxUserRepository.FindTenantsByLoginAsync(CurrentUser.UserName);
return new PagedResultDto<LookupDto<string>>
{
TotalCount = items.Count(),
Items = ObjectMapper.Map<List<Tenant>, List<LookupDto<string>>>(items)
};
}
<div *ngIf="user.isAuthenticated" class="dropdown btn-group" ngbDropdown>
<a
class="btn"
role="button"
id="dropdownMenuTenantsLink"
ngbDropdownToggle
*ngIf="(selectedTenant$ | async)?.name as tenantName"
>
<span>{{ '::Tenants:CurrentTenant' | abpLocalization }}: <b>{{ tenantName }}</b></span>
</a>
<div
ngbDropdownMenu
class="dropdown-menu dropdown-menu-right"
*ngIf="dropdownTenants$ | async"
>
<h6 class="dropdown-header">{{ '::Tenants:SwitchTenant' | abpLocalization }}</h6>
<a
*ngFor="let tenant of dropdownTenants$ | async"
class="dropdown-item pointer"
(click)="switchTenant(user.userName, tenant)"
>
{{ tenant.displayName }}</a
>
</div>
</div>
switchTenant(userName: string, tenant: Common.Lookup<string>) {
this.oAuthService.configure(
this.store.selectSnapshot(ConfigState.getOne('environment')).oAuthConfig,
);
return from(this.oAuthService.loadDiscoveryDocument())
.pipe(
switchMap(() =>
from(
this.oAuthService.fetchTokenUsingGrant(
'Custom', // why we cannot use own name??
null,
new HttpHeaders(
{ ...(tenant.id && { __tenant: tenant.id })}
&& (userName && { user: userName })
)
),
),
),
switchMap(() => this.store.dispatch(new GetAppConfiguration())),
tap(() => {
const redirectUrl =
snq(() => window.history.state.redirectUrl) || (this.options || {}).redirectUrl || '/';
this.store.dispatch(new Navigate([redirectUrl]));
}),
take(1),
).subscribe(() => {});
}
All in all, the idea is:
in app service layer to get the list of all tenants for current user (login name) - see above;
fill dropdown of tenants for passwordless login and supply the tenant id for each entry - see above;
make request from Angular app (using oAuthService->[some passwordless workflow?]) supplying the access token of currently authenticated user, some custom passwordless grant-type and tenant id in order to login (custom extension validator is going to intercept this request on server-side and approve or reject the login).
is the most tricky part, since OAuthService still does not support custom grant type. I've tried to patch the latest angular-oauth2-oidc from github (10.x) and add fetchTokenUsingGrant, but how to update our solution to the patched version? Your framework uses this package inside and I even cannot see angular-oauth2-oidc via npm outdated.