Hi,
You can override the
AccountAppService
andEmailConfirmation
[Dependency(ReplaceServices = true)] [ExposeServices(typeof(AccountAppService))] public class MyAccountAppService : AccountAppService { .... public override async Task ConfirmEmailAsync(ConfirmEmailInput input) { var user = await UserManager.GetByIdAsync(input.UserId); if (user.EmailConfirmed) { return; } (await UserManager.ConfirmEmailAsync(user, input.Token)).CheckErrors(); (await UserManager.UpdateSecurityStampAsync(user)).CheckErrors(); await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext { Identity = IdentitySecurityLogIdentityConsts.Identity, Action = IdentitySecurityLogActionConsts.ChangeEmail }); } }
[Dependency(ReplaceServices = true)] [ExposeServices(typeof(EmailConfirmationModel))] public class MyEmailConfirmationModel : EmailConfirmationModel { ... public override async Task<IActionResult> OnGetAsync() { ReturnUrl = GetRedirectUrl(ReturnUrl, ReturnUrlHash); try { var user = await UserManager.GetByIdAsync(UserId); if (user.EmailConfirmed) { EmailConfirmed = true; return Page(); } ValidateModel(); InvalidToken = !await AccountAppService.VerifyEmailConfirmationTokenAsync( new VerifyEmailConfirmationTokenInput() { UserId = UserId, Token = ConfirmationToken } ); if (!InvalidToken) { await _accountAppService.ConfirmEmailAsync(new ConfirmEmailInput { UserId = UserId, Token = ConfirmationToken }); EmailConfirmed = true; } } catch (Exception e) { if (e is AbpIdentityResultException && !string.IsNullOrWhiteSpace(e.Message)) { Alerts.Warning(GetLocalizeExceptionMessage(e)); return Page(); } if (e is AbpValidationException) { return Page(); } throw; } return Page(); } }
Hi Liang, thanks for the answer. I replaced the ConfirmEmail by adding a "CustomEmailConfirmation" Page under /Pages/Account/CustomEmailConfirmationModel.html and CustomEmailConfirmationModel.cs
I am not sure for the "AppService". I added it under the same /Pages/Account and just a class with the code you sent.
I added these changes and the Token that I get on the email still shows as invalid
Am I adding in the wrong section the override for the "AppService"?
Here it is how I added it:
Regards,
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.<>c__DisplayClass14_0.<UseSingleConstructorActivation>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.<>c__DisplayClass14_0.<BuildPipeline>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.<>c__DisplayClass14_0.<BuildPipeline>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?
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 aLogin 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?
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 aLogin 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?
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.
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.
Hello abpnewtonvisionco,
I have checked your code, I think you are missing to add
File
in yourgenerateFormData
method ->Could you please try with this code
private generateFormData(file: File | null) { if (!file) { return null; } const formData = new FormData(); formData.append('file', file); formData.append('fileName', file.name); formData.append('contentType', file.type); formData.append('contentLength', file.size.toString()); return formData; }
Please do let us know if this helps you or if anything else is needed
Thank you, Anjali
Hey Anjali, any input with the new answer that I posted?