hi
Try to clear the Redis. If it still does not work. Can you share a simple project?
liming.ma@volosoft.com
ok
hi
In this case, I must find a way to reproduce the problem. Do you have any ideas?
hi
Authorization failed. These requirements were not met: PermissionRequirement: Chat.Messaging
https://support.abp.io/QA/Questions/4151/Need-a-guide-about--chat--module-in-blazor-server#answer-0b74bde7-8a10-5844-7414-3a07f7806f23
Please add ChatPermissions
to current user.
And write some logs on this handle to ensure the token has been converted.
app.Use(async (httpContext, next) =>
{
var accessToken = httpContext.Request.Query["access_token"];
var path = httpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/signalr-hubs/chat")))
{
httpContext.Request.Headers["Authorization"] = "Bearer " + accessToken;
}
await next();
});
hi
Share your logs again. Thanks.
The project that is using
context.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(365);
})
.AddAbpOpenIdConnect("oidc", options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.ClientId = configuration["AuthServer:ClientId"];
options.ClientSecret = configuration["AuthServer:ClientSecret"];
options.UsePkce = true;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("roles");
options.Scope.Add("email");
options.Scope.Add("phone");
options.Scope.Add("MyProjectName");
});
These codes will write the Error logs. Please share the logs of web host.
Thanks
liming.ma@volosoft.com
hi
Add below code to your Web.Host project
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.Http.Client.IdentityModel.Web;
using Volo.Abp.IdentityModel;
namespace MyCompanyName.MyProjectName.Web;
[Dependency(ReplaceServices = true)]
public class MyHttpContextIdentityModelRemoteServiceHttpClientAuthenticator : HttpContextIdentityModelRemoteServiceHttpClientAuthenticator
{
public ILogger<MyHttpContextIdentityModelRemoteServiceHttpClientAuthenticator> Logger { get; set; }
public MyHttpContextIdentityModelRemoteServiceHttpClientAuthenticator(IIdentityModelAuthenticationService identityModelAuthenticationService,
ILogger<MyHttpContextIdentityModelRemoteServiceHttpClientAuthenticator> logger)
: base(identityModelAuthenticationService)
{
Logger = logger;
}
public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
{
if (context.RemoteService.GetUseCurrentAccessToken() != false)
{
var accessToken = await GetAccessTokenFromHttpContextOrNullAsync();
if (accessToken != null)
{
context.Request.SetBearerToken(accessToken);
return;
}
}
await base.Authenticate(context);
}
protected async override Task<string> GetAccessTokenFromHttpContextOrNullAsync()
{
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext == null)
{
Logger.LogError("Could not get HttpContext!");
return null;
}
var token = await httpContext.GetTokenAsync("access_token");
if (token.IsNullOrEmpty())
{
Logger.LogError("Could not get access_token!");
return null;
}
Logger.LogError("access_token: " + token);
return token;
}
}
using System.Globalization;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies;
using Volo.Abp.AspNetCore.Mvc.Client;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
using Volo.Abp.Users;
namespace MyCompanyName.MyProjectName.Web;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(ICachedApplicationConfigurationClient))]
public class MyMvcCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency
{
public ILogger<MvcCachedApplicationConfigurationClient> Logger { get; set; }
protected IHttpContextAccessor HttpContextAccessor { get; }
protected AbpApplicationConfigurationClientProxy ApplicationConfigurationAppService { get; }
protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; }
protected ICurrentUser CurrentUser { get; }
protected IDistributedCache<ApplicationConfigurationDto> Cache { get; }
protected AbpAspNetCoreMvcClientCacheOptions Options { get; }
public MyMvcCachedApplicationConfigurationClient(
IDistributedCache<ApplicationConfigurationDto> cache,
AbpApplicationConfigurationClientProxy applicationConfigurationAppService,
ICurrentUser currentUser,
IHttpContextAccessor httpContextAccessor,
AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy,
IOptions<AbpAspNetCoreMvcClientCacheOptions> options, ILogger<MvcCachedApplicationConfigurationClient> logger)
{
ApplicationConfigurationAppService = applicationConfigurationAppService;
CurrentUser = currentUser;
HttpContextAccessor = httpContextAccessor;
ApplicationLocalizationClientProxy = applicationLocalizationClientProxy;
Logger = logger;
Options = options.Value;
Cache = cache;
}
public async Task<ApplicationConfigurationDto> GetAsync()
{
var cacheKey = CreateCacheKey();
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
{
return configuration;
}
configuration = await Cache.GetOrAddAsync(
cacheKey,
async () => await GetRemoteConfigurationAsync(),
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = Options.ApplicationConfigurationDtoCacheAbsoluteExpiration
}
);
if (httpContext != null)
{
httpContext.Items[cacheKey] = configuration;
}
Logger.LogError(JsonSerializer.Serialize(configuration, new JsonSerializerOptions()
{
WriteIndented = true
}));
return configuration;
}
private async Task<ApplicationConfigurationDto> GetRemoteConfigurationAsync()
{
var config = await ApplicationConfigurationAppService.GetAsync(
new ApplicationConfigurationRequestOptions
{
IncludeLocalizationResources = false
}
);
var localizationDto = await ApplicationLocalizationClientProxy.GetAsync(
new ApplicationLocalizationRequestDto {
CultureName = config.Localization.CurrentCulture.Name,
OnlyDynamics = true
}
);
config.Localization.Resources = localizationDto.Resources;
return config;
}
public ApplicationConfigurationDto Get()
{
var cacheKey = CreateCacheKey();
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
{
return configuration;
}
return AsyncHelper.RunSync(GetAsync);
}
protected virtual string CreateCacheKey()
{
return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser);
}
}
static class MvcCachedApplicationConfigurationClientHelper
{
public static string CreateCacheKey(ICurrentUser currentUser)
{
var userKey = currentUser.Id?.ToString("N") ?? "Anonymous";
return $"ApplicationConfiguration_{userKey}_{CultureInfo.CurrentUICulture.Name}";
}
}
hi
I will share some code with you, then you can test it on production.