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 dear support team. I need a custom authorization flow on my ABP application please guide me. I am very confused.
I have a web application that is hosted by Telegram Web App. This is a React application implemented in NextJS. The only thing I have access to is the token that Telegram produces. It gives me a hash string and its decryption key to validate that this request was sent by a user in Telegram. I want to auto-register every user who opened my Telegram app if they are not registered before. After confirming the token sent by Telegram, which has a userId, create a user with their Telegram ID as username and give them default roles. I also want users to access their account on the dashboard, which is the ABP admin web, without the need for a password using the Telegram Login widget, it has the same algorithm and I want to authenticate users using telegram token. What is the best flow I can use to handle this in ABP Studio MS Template (openid) please?
here is an overview of the data I can use to validate request:
using System;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Linq;
namespace Telegram
{
/// <summary>
/// A helper class used to verify authorization data
/// </summary>
public class LoginWidget : IDisposable
{
/// <summary>
/// How old (in seconds) can authorization attempts be to be considered valid (compared to the auth_date field)
/// </summary>
public long AllowedTimeOffset = 30;
private bool _disposed = false;
private readonly HMACSHA256 _hmac;
private static readonly DateTime _unixStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// Construct a new <see cref="LoginWidget"/> instance
/// </summary>
/// <param name="token">The bot API token used as a secret parameter when checking authorization</param>
public LoginWidget(string token)
{
if (token == null) throw new ArgumentNullException(nameof(token));
using (SHA256 sha256 = SHA256.Create())
{
_hmac = new HMACSHA256(sha256.ComputeHash(Encoding.ASCII.GetBytes(token)));
}
}
/// <summary>
/// Checks whether the authorization data received from the user is valid
/// </summary>
/// <param name="fields">A collection containing query string fields as sorted key-value pairs</param>
/// <returns></returns>
public Authorization CheckAuthorization(SortedDictionary<string, string> fields)
{
if (_disposed) throw new ObjectDisposedException(nameof(LoginWidget));
if (fields == null) throw new ArgumentNullException(nameof(fields));
if (fields.Count < 3) return Authorization.MissingFields;
if (!fields.ContainsKey(Field.Id) ||
!fields.TryGetValue(Field.AuthDate, out string authDate) ||
!fields.TryGetValue(Field.Hash, out string hash)
) return Authorization.MissingFields;
if (hash.Length != 64) return Authorization.InvalidHash;
if (!long.TryParse(authDate, out long timestamp))
return Authorization.InvalidAuthDateFormat;
if (Math.Abs(DateTime.UtcNow.Subtract(_unixStart).TotalSeconds - timestamp) > AllowedTimeOffset)
return Authorization.TooOld;
fields.Remove(Field.Hash);
StringBuilder dataStringBuilder = new StringBuilder(256);
foreach (var field in fields)
{
if (!string.IsNullOrEmpty(field.Value))
{
dataStringBuilder.Append(field.Key);
dataStringBuilder.Append('=');
dataStringBuilder.Append(field.Value);
dataStringBuilder.Append('\n');
}
}
dataStringBuilder.Length -= 1; // Remove the last \n
byte[] signature = _hmac.ComputeHash(Encoding.UTF8.GetBytes(dataStringBuilder.ToString()));
// Adapted from: https://stackoverflow.com/a/14333437/6845657
for (int i = 0; i < signature.Length; i++)
{
if (hash[i * 2] != 87 + (signature[i] >> 4) + ((((signature[i] >> 4) - 10) >> 31) & -39)) return Authorization.InvalidHash;
if (hash[i * 2 + 1] != 87 + (signature[i] & 0xF) + ((((signature[i] & 0xF) - 10) >> 31) & -39)) return Authorization.InvalidHash;
}
return Authorization.Valid;
}
/// <summary>
/// Checks whether the authorization data received from the user is valid
/// </summary>
/// <param name="fields">A collection containing query string fields as key-value pairs</param>
/// <returns></returns>
public Authorization CheckAuthorization(Dictionary<string, string> fields)
{
if (fields == null) throw new ArgumentNullException(nameof(fields));
return CheckAuthorization(new SortedDictionary<string, string>(fields, StringComparer.Ordinal));
}
/// <summary>
/// Checks whether the authorization data received from the user is valid
/// </summary>
/// <param name="fields">A collection containing query string fields as key-value pairs</param>
/// <returns></returns>
public Authorization CheckAuthorization(IEnumerable<KeyValuePair<string, string>> fields) =>
CheckAuthorization(fields?.ToDictionary(f => f.Key, f => f.Value, StringComparer.Ordinal));
/// <summary>
/// Checks whether the authorization data received from the user is valid
/// </summary>
/// <param name="fields">A collection containing query string fields as key-value pairs</param>
/// <returns></returns>
public Authorization CheckAuthorization(IEnumerable<Tuple<string, string>> fields) =>
CheckAuthorization(fields?.ToDictionary(f => f.Item1, f => f.Item2, StringComparer.Ordinal));
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
_hmac?.Dispose();
}
}
private static class Field
{
public const string AuthDate = "auth_date";
public const string Id = "id";
public const string Hash = "hash";
}
}
public enum Authorization
{
InvalidHash,
MissingFields,
InvalidAuthDateFormat,
TooOld,
Valid
}
}
Hi dear support team. I want to extend IdentityUser using modules source code and add ability to register via socialNetwork ID and the socialNetwork auth token. They should be able to login outside of the social network and manage their data on the web client. Also, I want to use the social network username as their IdentityUser.Username to use it as user finder. I think module extending system can't help us because we also need to add extra claims and custom grant type for openiddict based on these data.
IdentityUser.Username: SocialUserName //string // static // changeable via social_auth_token (if they change their username) IdentityUser.SocialUserId: SocialUserID //long // static IdentityUser.IsBot: SocialUserIsBot // bool IdentityUser.IsPremium: SocialUserIsPremium // bool
please I request you, guide me, what should I pay attention to when I added these new properties to the IdentityUser and if there is an article about doing these things step by step, please share with me. Thank you.
P.S: My project's module references (free & pro) are locally but framework is nuget package reference.
Is there a way to replace modules (PRO & FREE) with source code but keep framework? I want to do this inside CI, so manually change can't help.
I have tried switch-to-local --paths "path\to\pro\free\modules\"
with batch get-source for all modules. but didn't work for framework references inside free modules.
My CI has +1K package conflict error with netstandard2.0 on my solution when I trying to graph build my project with local framework reference:
conflict System.Runtime 5.x and System.Runtime 8.x inside every proj has reference to Volo.Abp.Core
Why do we still have the netstandard2.0?
I have tried -p:TargetFramework=net8.0
and didn't help
Volo.CmsKit.Pro.Application.Contracts
to the MyProject.CmsService.Contracts
Volo.CmsKit.Pro.Application
, Volo.CmsKit.Pro.HttpApi
and Volo.CmsKit.Pro.MongoDB
to the MyProject.CmsService
Volo.CmsKit.Pro.Domain.Shared
to the MyProject.AdministrationService
for permissions and featuresVolo.CmsKit.Pro.Web
, Volo.CmsKit.Pro.HttpApi.Client
and MyProject.CmsService.Contracts
to the MyProject.Web
CmsKit
and CmsKitPro
global features for
MyProject.CmsService.Contracts
MyProject.AdministrationService
MyProject.Web
ICmsKitProMongoDbContext
and ICmsKitMongoDbContext
via CmsServiceDbContext
using ReplaceDbContext
attribute.What did I forget?
I want to support login via wallet, where the users have a linked web3 wallet to their account. Is there any useful document/article around this? We have the wallet address and a base64 public key after login submitted from the client.
[ERR] Unable to cast object of type 'Volo.Chat.Users.ChatUser' to type 'Volo.Abp.Users.IUserData'.
System.InvalidCastException: Unable to cast object of type 'Volo.Chat.Users.ChatUser' to type 'Volo.Abp.Users.IUserData'.
at System.Linq.Enumerable.CastIterator[TResult](IEnumerable source)+MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Volo.Abp.Users.UserLookupService`2.SearchAsync(String sorting, String filter, Int32 maxResultCount, Int32 skipCount, CancellationToken cancellationToken) in D:\github\hitasp\abp\modules\users\src\Volo.Abp.Users.Domain\Volo\Abp\Users\UserLookupService.cs:line 171
at Volo.Chat.Users.ContactAppService.GetContactsAsync(GetContactsInput input) in D:\github\hitasp\volo\abp\chat\src\Volo.Chat.Application\Volo\Chat\Users\ContactAppService.cs:line 44
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:line 24
at Volo.Abp.Features.FeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation) in D:\github\hitasp\abp\framework\src\Volo.Abp.Features\Volo\Abp\Features\FeatureInterceptor.cs:line 28
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:line 29
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:line 24
at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation) in D:\github\hitasp\abp\framework\src\Volo.Abp.GlobalFeatures\Volo\Abp\GlobalFeatures\GlobalFeatureInterceptor.cs:line 25
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:line 29
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:line 24
at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) in D:\github\hitasp\abp\framework\src\Volo.Abp.Validation\Volo\Abp\Validation\ValidationInterceptor.cs:line 19
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:line 29
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:line 24
at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) in D:\github\hitasp\abp\framework\src\Volo.Abp.Authorization\Volo\Abp\Authorization\AuthorizationInterceptor.cs:line 19
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:line 29
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:line 24
at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, AbpAuditingOptions options, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope) in D:\github\hitasp\abp\framework\src\Volo.Abp.Auditing\Volo\Abp\Auditing\AuditingInterceptor.cs:line 98
at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation) in D:\github\hitasp\abp\framework\src\Volo.Abp.Auditing\Volo\Abp\Auditing\AuditingInterceptor.cs:line 40
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:line 29
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:line 24
at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) in D:\github\hitasp\abp\framework\src\Volo.Abp.Uow\Volo\Abp\Uow\UnitOfWorkInterceptor.cs:line 49
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) in D:\github\hitasp\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:line 29
at lambda_method1751(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
//Messaging Service Client
await CreateApplicationAsync(
name: "MessagingService",
type: OpenIddictConstants.ClientTypes.Confidential,
consentType: OpenIddictConstants.ConsentTypes.Implicit,
displayName: "Messaging Service Client",
secret: "1q2w3e*",
grantTypes: new List<string>
{
OpenIddictConstants.GrantTypes.ClientCredentials
},
scopes: commonScopes.Union(new[] { "IdentityService" }).ToList(),
permissions: new List<string> { IdentityPermissions.UserLookup.Default }
);
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IdentityUserLookupController), IncludeSelf = true)]
public class IdentityServiceController : IdentityUserLookupController
{
public IdentityServiceController(
IIdentityUserLookupAppService lookupAppService) : base(lookupAppService)
{
}
public override async Task<UserData> FindByIdAsync(Guid id)
{
return await base.FindByIdAsync(id);
}
}
tye run
api/chat/contact/contacts
What did I miss?System.InvalidOperationException: The type 'vAnOhd8kBREcGO1P7Oo.vERgfT88EFtV78GBxyV' is not a valid page. A page must define a public, non-static 'Model' property.
at Microsoft.AspNetCore.Mvc.ApplicationModels.DefaultPageApplicationModelProvider.CreateModel(PageActionDescriptor actionDescriptor, TypeInfo pageTypeInfo)
at Microsoft.AspNetCore.Mvc.ApplicationModels.DefaultPageApplicationModelProvider.OnProvidersExecuting(PageApplicationModelProviderContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.CompiledPageActionDescriptorFactory.CreateCompiledDescriptor(PageActionDescriptor actionDescriptor, CompiledViewDescriptor viewDescriptor)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageLoader.LoadAsyncCore(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageLoaderMatcherPolicy.ApplyAsyncAwaited(CandidateSet candidates, Task`1 actionDescriptorTask, Int32 index)
at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.SelectEndpointWithPoliciesAsync(HttpContext httpContext, IEndpointSelectorPolicy[] policies, CandidateSet candidateSet)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.<Invoke>g__AwaitMatch|8_1(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matchTask)
at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
abp new Acme.BookStore -t microservice-pro --preview && cd shared/Acme.BookStore.DbMigrator && dotnet run
./run-tye.ps1
Unziped version of cached template has this problem too, with same vAnOhd8kBREcGO1P7Oo.vERgfT88EFtV78GBxyV
type error
I want to use local reference of abp framework, but when try to run template abp framework packages downloaded beacuse of licensing package's dependencies. Then we got packages dublicated. How to fix?
Is it possible?