Open Closed

ABP with ELSA using MicroService based solution #5831


User avatar
0
abpnewtonvisionco created
  • ABP Framework version: v7.2.2
  • UI Type: Angular
  • Database System: EF Core (SQL Server)
  • ** Auth Server Separated (for Angular)**: yes
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

Hey team,

Currently we are implementing ELSA, I created a new microservice to the solution (we are using microservice based solution with Angular). And followed this tutorial:

https://community.abp.io/posts/using-elsa-workflow-with-the-abp-framework-773siqi9

I am able to see the dashboard and everything. However when I add the

@attribute [Authorize(ElsaServicePermissions.ElsaDashboard)]*

the dashboard disappears (even though I have the user configured for that specific permission), when I check the User information it doesn't have the user identification. (it is like if I was not logged in).

This is how I do it:

I fire up the microservice, and then I go to the swagger, log in there. And then just go back to the dashboard url.

Besides this, since ELSA is not an angular module, we are using a resolver that just pick ups the request and pastes the url so it sends it to the ELSA url service. I want to know if there is a better way to do this. As I want to show/hide this elsa redirection using the permissions

Thanks!


10 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Which project are you adding the ELSA dashboard to?

    Similar questions: https://support.abp.io/QA/Questions/5733#answer-3a0db883-c466-1f48-be6b-ec834293db61

  • User Avatar
    0
    abpnewtonvisionco created

    hi

    Which project are you adding the ELSA dashboard to?

    Similar questions: https://support.abp.io/QA/Questions/5733#answer-3a0db883-c466-1f48-be6b-ec834293db61

    Hi,

    I am adding it in the HttpApi.Host project like this:

    This is the Configuration inside ConfigureServices method for ELSA in the ApiHostModule:

    And this is the configuration inside OnApplicationInitialization method.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can add a cookies authentication to your HttpApi.Host project.

    https://support.abp.io/QA/Questions/5733#answer-3a0db883-c466-1f48-be6b-ec834293db61

  • User Avatar
    0
    abpnewtonvisionco created

    hi

    You can add a cookies authentication to your HttpApi.Host project.

    https://support.abp.io/QA/Questions/5733#answer-3a0db883-c466-1f48-be6b-ec834293db61

    Hey, I added it however I am not quite sure it works as I see the user is authenticated but it does not contain any of the permissions.

    Then I am using the Authorization service to check if the incoming user actually does have that info but it throws an error Also, when you add those links for the questions it just takes me back to the forum page and no to something specific.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    You don't seem to refer to the code I shared. You should first authenticate the user and then issue cookies. The cookies should contain correct user information, not a Login claim. Then, try to authenticate the cookies in the middleware.

  • User Avatar
    0
    abpnewtonvisionco created

    You don't seem to refer to the code I shared.
    You should first authenticate the user and then issue cookies. The cookies should contain correct user information, not a Login claim. Then, try to authenticate the cookies in the middleware.

    As I mentioned in my last reply, the link for the answers you send does not redirect me to somewhere in particular. It just takes me back to the forum page. Is there something in particular that I should look in the forum?

    Since the url changes maybe is a question that has a private mode?

  • User Avatar
    0
    abpnewtonvisionco created

    You don't seem to refer to the code I shared.
    You should first authenticate the user and then issue cookies. The cookies should contain correct user information, not a Login claim. Then, try to authenticate the cookies in the middleware.

    Also I am not quite sure if this is what you mean:

    isn't this already default behavior for ABP microservices?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    maybe is a question that has a private mode?

    Yes you are right.

    The answer detail is :

    hi

    You can add cookies authentication to your API website. Issue cookies after appropriate verification.

    After that, AbpHangfireAuthorizationFilter will work on the API website.

    public class HomeController : AbpController
    {
        public async Task<ActionResult> Index(string username, string password)
        {
            if (username == "admin" && password == "1q2w3E*")
            {
                var user = await HttpContext.RequestServices.GetRequiredService<IdentityUserManager>().FindByNameAsync(username);
                var userClaimsPrincipalFactory = HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser>>();
                await HttpContext.SignInAsync("HangFireCookie", await userClaimsPrincipalFactory.CreateAsync(user!));
            }
    
            return Redirect("~/swagger");
        }
    }
    
    
    Depends On typeof(AbpIdentityAspNetCoreModule)
    
        <ProjectReference Include="..\..\..\..\..\..\..\abp\modules\identity\src\Volo.Abp.Identity.AspNetCore\Volo.Abp.Identity.AspNetCore.csproj" />
    
    context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = configuration["AuthServer:Authority"];
        options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
        options.Audience = "_3M";
    })
    .AddCookie("HangFireCookie", options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromHours(2);
    });
    
    app.UseAuthentication();
    
    app.Use(async (ctx, next) =>
    {
        if (ctx.User.Identity?.IsAuthenticated != true)
        {
            var result = await ctx.AuthenticateAsync("HangFireCookie");
            if (result.Succeeded && result.Principal != null)
            {
                ctx.User = result.Principal;
            }
        }
    
        await next();
    });
    
    if (MultiTenancyConsts.IsEnabled)
    {
        app.UseMultiTenancy();
    }
    
    app.UseAuthorization();
    
  • User Avatar
    0
    abpnewtonvisionco created

    maybe is a question that has a private mode?

    Yes you are right.

    The answer detail is :

    hi

    You can add cookies authentication to your API website. Issue cookies after appropriate verification.

    After that, AbpHangfireAuthorizationFilter will work on the API website.

    public class HomeController : AbpController 
    { 
        public async Task<ActionResult> Index(string username, string password) 
        { 
            if (username == "admin" && password == "1q2w3E*") 
            { 
                var user = await HttpContext.RequestServices.GetRequiredService<IdentityUserManager>().FindByNameAsync(username); 
                var userClaimsPrincipalFactory = HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser>>(); 
                await HttpContext.SignInAsync("HangFireCookie", await userClaimsPrincipalFactory.CreateAsync(user!)); 
            } 
     
            return Redirect("~/swagger"); 
        } 
    } 
     
    
    Depends On typeof(AbpIdentityAspNetCoreModule) 
    
        <ProjectReference Include="..\..\..\..\..\..\..\abp\modules\identity\src\Volo.Abp.Identity.AspNetCore\Volo.Abp.Identity.AspNetCore.csproj" /> 
    
    context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
    .AddJwtBearer(options => 
    { 
        options.Authority = configuration["AuthServer:Authority"]; 
        options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); 
        options.Audience = "_3M"; 
    }) 
    .AddCookie("HangFireCookie", options => 
    { 
        options.ExpireTimeSpan = TimeSpan.FromHours(2); 
    }); 
    
    app.UseAuthentication(); 
     
    app.Use(async (ctx, next) => 
    { 
        if (ctx.User.Identity?.IsAuthenticated != true) 
        { 
            var result = await ctx.AuthenticateAsync("HangFireCookie"); 
            if (result.Succeeded && result.Principal != null) 
            { 
                ctx.User = result.Principal; 
            } 
        } 
     
        await next(); 
    }); 
     
    if (MultiTenancyConsts.IsEnabled) 
    { 
        app.UseMultiTenancy(); 
    } 
     
    app.UseAuthorization(); 
    

    Thanks for the answer Lian,

    I added these changes however when I hit this controller I am getting an error when resolving the "GetRequiredService":

    Autofac.Core.DependencyResolutionException: An exception was thrown while activating Castle.Proxies.IdentityUserManagerProxy.
     ---> Autofac.Core.DependencyResolutionException: None of the constructors found on type 'Castle.Proxies.IdentityUserManagerProxy' can be invoked with the available services and parameters:
    Cannot resolve parameter 'Volo.Abp.Identity.IIdentityRoleRepository roleRepository' of constructor 'Void .ctor(Castle.DynamicProxy.IInterceptor[], Volo.Abp.Identity.IdentityUserStore, Volo.Abp.Identity.IIdentityRoleRepository, Volo.Abp.Identity.IIdentityUserRepository, Microsoft.Extensions.Options.IOptions`1[Microsoft.AspNetCore.Identity.IdentityOptions], Microsoft.AspNetCore.Identity.IPasswordHasher`1[Volo.Abp.Identity.IdentityUser], System.Collections.Generic.IEnumerable`1[Microsoft.AspNetCore.Identity.IUserValidator`1[Volo.Abp.Identity.IdentityUser]], System.Collections.Generic.IEnumerable`1[Microsoft.AspNetCore.Identity.IPasswordValidator`1[Volo.Abp.Identity.IdentityUser]], Microsoft.AspNetCore.Identity.ILookupNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber, System.IServiceProvider, Microsoft.Extensions.Logging.ILogger`1[Volo.Abp.Identity.IdentityUserManager], Volo.Abp.Threading.ICancellationTokenProvider, Volo.Abp.Identity.IOrganizationUnitRepository, Volo.Abp.Settings.ISettingProvider)'.
    
    See https://autofac.rtfd.io/help/no-constructors-bindable for more info.
       at Autofac.Core.Activators.Reflection.ReflectionActivator.&lt;&gt;c__DisplayClass14_0.&lt;UseSingleConstructorActivation&gt;b__0(ResolveRequestContext ctxt, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
       at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
       at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext ctxt, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
       at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
    

    Let me add screenshots on how my HttpApiHostModule looks:

    I am wondering if its because a wrong using that I have on the controller?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Could you share a project that can reproduce the problem with me? I will check it out. shiwei.liang@volosoft.com

Made with ❤️ on ABP v9.1.0-preview. Updated on November 01, 2024, 05:35