"dev@veek.vn" 'in aktiviteleri

It works now :D

thank you @liangshiwei

How about registering the route for that? I mean, click on the menu to open my component

I mean Administration, not Setting tab

Hi,

I was wondering if there is a way to add additional settings to Administration pages,

Beside, I want to add main menu and sub menus in Angular?

ABP Framework version: v.7.3.2 UI Type: Angular Database System: MongoDB Tiered (for MVC) or Auth Server Separated (for Angular): yes Exception message and full stack trace: Steps to reproduce the issue:

thanks @maliming, it works now

hi

 curl --location 'https://localhost:44369/connect/token' \ 
--header 'Content-Type: application/x-www-form-urlencoded' \ 
--data-urlencode 'grant_type=PasswordlessExtensionGrant' \ 
--data-urlencode 'client_id=DemoNewGrantType_App' \ 
--data-urlencode 'phoneNumber=0344446301' \ 
--data-urlencode 'scope=openid offline_access DemoNewGrantType' 
{ 
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg0NzZDOTUwQjYxOTY2MkY2QUU4MTlGOUVDNzdEMzI0QkMyNDFFRDQiLCJ4NXQiOiJoSGJKVUxZWlppOXE2Qm41N0hmVEpMd2tIdFEiLCJ0eXAiOiJhdCtqd3QifQ.eyJzdWIiOiI3NWZjNDI1Yy1mMDY3LTlmODQtZWNkMy0zYTBmNDZlY2UxZWUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AYWJwLmlvIiwicm9sZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6ImFkbWluIiwicGhvbmVfbnVtYmVyIjoiMDM0NDQ0NjMwMSIsInBob25lX251bWJlcl92ZXJpZmllZCI6IlRydWUiLCJlbWFpbF92ZXJpZmllZCI6IkZhbHNlIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsIm9pX3Byc3QiOiJEZW1vTmV3R3JhbnRUeXBlX0FwcCIsIm9pX2F1X2lkIjoiNzRjOTkyZjQtYzNjMS1kYThmLWM5MzAtM2EwZjQ2ZjQ5NjUwIiwiY2xpZW50X2lkIjoiRGVtb05ld0dyYW50VHlwZV9BcHAiLCJvaV90a25faWQiOiI4MTgzODlhOC1mNDQxLTVjODgtNDZmYS0zYTBmNDZmNDk3ZTAiLCJhdWQiOiJEZW1vTmV3R3JhbnRUeXBlIiwic2NvcGUiOiJvcGVuaWQgb2ZmbGluZV9hY2Nlc3MgRGVtb05ld0dyYW50VHlwZSIsImp0aSI6ImQ2MTU5ZjBjLTFlMDQtNDc0NC1iM2EyLWY4ZmY4NGEyYTQyMiIsImV4cCI6MTcwMTY5NjE1NSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNTYvIiwiaWF0IjoxNzAxNjkyNTU1fQ.KZs_2YXYy2sUjQ7K5nOSYKf5MRDBHgbr5AhKeIy6LIworGs6lFXDFde7IdILagvSlxbK7qDC2QdN1pBOemDTyckUtPHKne5hfvX7ZIQrS5FnEPkff9rMqH9E8rwA9x0DukiH5HIuhT5qLps_sXvVhngp1oa7fwiV6_WcfDud_F_qgimOcfXuPzL_ifSYe1Vb8b8vf-lKU5t8ucrrGM9aPBTa9TOs7-5gMabRcksbDhGtVyyTOXRtItI242lZR5msDTElgF59QQNAPXJzKH6cY-A-_2NTyI7LYmeqY5_q43xIfWAEF0seHoWwTSgb89AdZfF-qChQUGIjcX7JyHpdOw", 
  "token_type": "Bearer", 
  "expires_in": 3598, 
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg0NzZDOTUwQjYxOTY2MkY2QUU4MTlGOUVDNzdEMzI0QkMyNDFFRDQiLCJ4NXQiOiJoSGJKVUxZWlppOXE2Qm41N0hmVEpMd2tIdFEiLCJ0eXAiOiJKV1QifQ.eyJzdWIiOiI3NWZjNDI1Yy1mMDY3LTlmODQtZWNkMy0zYTBmNDZlY2UxZWUiLCJvaV9hdV9pZCI6Ijc0Yzk5MmY0LWMzYzEtZGE4Zi1jOTMwLTNhMGY0NmY0OTY1MCIsImF6cCI6IkRlbW9OZXdHcmFudFR5cGVfQXBwIiwiYXRfaGFzaCI6Iks2OHQtdFBFOFpBbk1TZFh5UFIza3ciLCJvaV90a25faWQiOiIxNmMzOWNjYy1lYmY4LTZjYTctYjYzOC0zYTBmNDZmNDliZTMiLCJhdWQiOiJEZW1vTmV3R3JhbnRUeXBlX0FwcCIsImV4cCI6MTcwMTY5Mzc1NSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNTYvIiwiaWF0IjoxNzAxNjkyNTU1fQ.eeB5O1R-a8lXnWaDsce1jSc6v8XK0CKYzYLAoo1odEtJbjubn45k_HZbXOXXuesUol-eB3rWYhtkvtZDgzVh6HO40-c39jH2BBitRuYgf9nPTwV6qrcKbJFZ2Z4_RRuJJyT4eK8kNrNPiovHm2yzrGLP0beylBPDv0UQz7E5CFcaZC6kPF8m1SXHx58hgdo9vLHxuAPkDxiyX4Q3isa3lijDdUK1ubtRhEEy5mGxaFLdNHY0IgVSMydmghPPGTqVPkHjHVjOxp1Zz85f7iKIjLRk--y5FD8X93NraEmynwR-pK05cKD7I-kEcpGkfDpdIyVbqhQHdGNUgW3VW7HuJQ", 
  "refresh_token": "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiI4NDc2Qzk1MEI2MTk2NjJGNkFFODE5RjlFQzc3RDMyNEJDMjQxRUQ0IiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.KeJzUD3N04KShYV2jUfsIRsloryqMXQLjsXMtRAbkW2pMbGunkLDHZTSEIypj9ECQQvjgp9rU2a2EGRLcbG6OsLIaY7e66cNywY8PvPjMJXOKNYAY8y1Xza2k4if8N5vvEh44HeqeEEQa3a2J0pmgeuJUT6hdbzKZt-fjmlBI9H23cYN0fVqPVS6Uf9yE45mnO-KvfuWeOxIZnOqvsX35j9EOsoYlJrhSwvvUPX5YGD-KOiyE9Erf0oQNV99UMSFvDHeKBPXMZvEXhboIkbaqoOLOlohP0DbkZTylZTk22n1Z6lQ-oPZMJqoykeAglbDiHn90xl1gA9mPwoHtZp2tQ.b4rnMNjBD72M9I9qdx29fQ.zh0bsUNMfXngES1Zo5jWI0WDgKIX4PekAsohDDUZFAaaZisqJWCFNudTIakzmLkQm1rQK19xx-94pyR03Tj8bzwopOmiYltLFmhWqyrh8xOeuTjYV2d8CByjyLD-xRu9kFSjqUHX2_RbN75yFBa-TlBs3b42fvNuEVbCB4CXvIXVfY1_jipyPRMCkWbO9s80qYrUgf9IfUvasfPLWANXxoh37eXz71cLAGv6cQj25TN4qUGO9S9PxenkuFUXFSOlqONYWGp0ZWEomWslgtpBkt8Ls2T8KqhdQqnNslAmCRZOd0kN0kPyF2a1S19Suhb7RYnd7XGKXSJZogDZTbkDN_gnGLvhD4yMbZX1ruke8p9Ef2l9YKKBe7zaUHSVMfpumLaFQRA-thQBo-V_ahRSnr0oQ6EM-5qL8DTpaJZXutYCJcpR3pscCMi5au-1pAerfDeKwpLHMFZJweyJItGgsfz1ouva6Fqpw_mTbucd5qT7xAn7hL9mXbUd9sGW12XE4a8uCslCi8h_EBD59N6ZwCsVDcvKaz1xggDsBbK0K8iO46AqiDVSXK4qjYrmyO1ouMUJrd9zfpp21y0-56OGpoBmt9JX2l1gdZyt6nItvipGhf7UZxH01WU81VKYeo_YvF7Y92HtQIIjQ1zesVUHJmbkgAC-80TGBRkI-wvkNm3N7tb8-gLOrJy8rHOuEjAB1dUFnaSHw7jtPLKE4uL2H2Ol8eV0Vp-LBKAzp8H-4tVUzqTR0P0NjVKT_1GeqhHoU-cNlwI9hKPW4Fh5Y6ETd3n1KmAJFj002WAZv_69MiE9OT7OZVjEzw9hjTw1vynUJ9yVwJmP8F6aAYzej5O-iQ1UA9jBnlAD0gbIe1cRabQAlP022NxzKJhyKMZN4xkuXxFMxMtqRn-2bwdPClJtM1IwGumFA_prp-e9Fi3eFVrnaXAL4XVhROlMvqwJ52vRKZ41zqkgMIwLC9D_zCtOXqjIckyK1VPZc3TUGGMCmCkGBM1m8Tw35qgtUfPwC1kybk2msG58TnytQzPZjJct-2l1w1N7uA6_xiMcEfAl1CYFTqeqGTaCuXmohFM_ObnOPQMOg1v-56QbbmSZOq6uSnFROEmDkfR4VMVwcvLtVAB0E1fF3y3W5z_G7g0iHHMeOoVvTs1xEwfvlUvvtKVSnV2HtoNT9tbGEnaAozTPeXEWaXgvz0zY4BZtKgeuezLNT9B8B5SVo4vhRrZFjlhp-kcfjK5idRTy1rMY1NT-gwNSJlC_JgOG-lfJ8qsOxg0vDdxa29funISTqfhw0aDFAhh9WFaFK9jO31hlu0cIAxs6Ys-Bpjq3U1GmwguNtJ3g8Ira_NwD-r9zBtf6GKPlxLaf0IJQsYSYVfBJiQ4nR9_59sAf-qMk_BQxYdzQ_qBci1-UC2D8EI-M4r1r1iMurWZ8rVMd1Z1Pp7RaRGuqRc748GXUg51NG6dLXmtDDHsigMHMM0cj0x3hs7kUTm5CsUA0WhUzA641Ej6M-tKZ-2Bm3q6DT7YXW38sqvb1k-F85bZxMBqxQcMu23Ox3r82YAqMy0pSKslpCvN57jhWg-ucnWGt3g851J13FxJTNq1HoFDQ70IRNG06C7uy_zK5JfsGPm-WBOnY9yukzaEiqXsArgzlRUpqR2qq357c97RUenzLDWw6KFj7JfpCapKPK_dsPkw_FPbxUF0zeYXQEfDegoALEGI53YIfrjm8XPqIw1PlqNP4zegxpkpJ8cy0CBmyQzU4FPpenEG3GNGVqBhfvzjsI1IcsjtYb0CBjC0Uw2QFbF_qPPb8e7TLrg3qMQ9xYbmmoTaId6CEWKMfxVOgDzXacbkO5dS9H7eY_UaG0NjfIuz1-4Z3KdJZ6xljjNwnzfW3i7hbwRlAE664gtorbVCl0mTmZM6LSmsJhKjKzWfSusZQi62WMxOfh6QUkAYOMDMdxIbPwcu4KOvTcNvVOB8YpLkqHch-0RUCLiNeFOjsGG-RKhtg3hxIBN7RCaEI-Kv4hSUK-dd_4hUXQyOsPI3ftuJdTvRXVD7sINA-nh-DIafI_G0tLHryeIkVeC_1jPb6_ynlkb9IWDJ0G7AtYl6ivl85z4b4Z2YqQoZWv1FEidPXq_-S9E-dazmjiFMf-Mu7mCiJ7InOrZmrWlBsy4N-c2nQfkSsnmliUyKdx2ISyi0M8EdDJF5X7tHyLTO9Zu7VjayFGKXJHFB2dZxEUt6xrw665k7WdUeH9iiJBNRWXNpH6H6cC8SiHal4W4Hu97SSAuTJ6oyHviZkXkYjM8a33BGAIpGdKqauvBbutTcPA1x1mmOeasAsd9G_F92bmSZGs9gJrmK_YHrEXrU7vInM5MJtmC1GmTj0ayoen8XlKJ4LItZm6sV6UoJrILToU1t3vRJ-poCJ6F8GjAHq3ltGaydFjKkXlzGXRkxBWOSs5BXVIhJE6V287s0VD2jLhdLHsHPtusbtyfbe8RmqynnA4jBPxieM_xvRkhCYATrhgF-0vwJcrXFKXcYcig.K6TpJpgb98WJjt8_fgWQS98m42FD3pKaUvlQ1ZiIdMQ" 
} 

I've added more setup and it's not working.

var issuerUrl = configuration["AuthServer:Authority"]; PreConfigure<OpenIddictServerBuilder>(builder => { builder.AddSigningCertificate(GetSigningCertificate(hostingEnvironment, configuration)); builder.AddEncryptionCertificate(GetSigningCertificate(hostingEnvironment, configuration));

builder.SetIssuer(new Uri(issuerUrl)); builder.SetAuthorizationEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/authorize"))); builder.SetTokenEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/token"))); builder.SetIntrospectionEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/introspect"))); builder.SetLogoutEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/logout"))); builder.SetRevocationEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/revocat"))); builder.SetUserinfoEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/userinfo"))); builder.SetDeviceEndpointUris(new Uri(Url.Combine(issuerUrl, "connect/device"))); builder.SetCryptographyEndpointUris(new Uri(Url.Combine(issuerUrl, ".well-known/jwks"))); builder.SetIdentityTokenLifetime(TimeSpan.FromMinutes(60)); builder.SetAccessTokenLifetime(TimeSpan.FromMinutes(60)); builder.SetAuthorizationCodeLifetime(TimeSpan.FromMinutes(60)); builder.SetDeviceCodeLifetime(TimeSpan.FromMinutes(60)); builder.SetRefreshTokenLifetime(TimeSpan.FromMinutes(60)); builder.SetUserCodeLifetime(TimeSpan.FromMinutes(60)); builder.Configure(openIddictServerOptions => { openIddictServerOptions.GrantTypes.Add(PasswordlessExtensionGrant.ExtensionGrantName); }); });

You can also make it simple.

public class PasswordlessExtensionGrant : ITokenExtensionGrant 
{ 
    public const string ExtensionGrantName = "PasswordlessExtensionGrant"; 
    public       string Name => ExtensionGrantName; 
 
    public async Task<IActionResult> HandleAsync(ExtensionGrantContext context) 
    { 
        // get phone number from request 
        var phoneNumber = context.Request.GetParameter("phoneNumber")?.Value?.ToString(); 
 
        if (string.IsNullOrEmpty(phoneNumber)) 
        { 
            return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme }, 
                                    properties: new AuthenticationProperties(new Dictionary<string, string> 
                                    { 
                                        [OpenIddictServerAspNetCoreConstants.Properties.Error] = 
                                            OpenIddictConstants.Errors.InvalidGrant 
                                    }!)); 
        } 
 
        // retrieve user 
        var userRepository = context.HttpContext.RequestServices.GetRequiredService<IRepository<IdentityUser, Guid>>(); 
        var user           = await userRepository.FirstOrDefaultAsync(x => x.PhoneNumber == phoneNumber); 
 
        if (user == null) 
        { 
            return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme }, 
                                    properties: new AuthenticationProperties(new Dictionary<string, string> 
                                    { 
                                        [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant 
                                    }!)); 
        } 
 
        var principal =  await context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<IdentityUser>>().CreateAsync(user); 
 
        // retrieve generic user claims 
        var userClaimsPrincipalFactory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<IdentityUser>>(); 
        var claimsPrincipal            = await userClaimsPrincipalFactory.CreateAsync(user); 
 
        claimsPrincipal.SetScopes(principal.GetScopes()); 
        claimsPrincipal.SetResources(await GetResourcesAsync(context, principal.GetScopes())); 
 
        // retrieve abp user claims 
        var abpClaimsPrincipalFactory = context.HttpContext.RequestServices.GetRequiredService<IAbpClaimsPrincipalFactory>(); 
        var abpClaimsPrincipal        = await abpClaimsPrincipalFactory.CreateAsync(claimsPrincipal); 
 
        await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, abpClaimsPrincipal); 
 
        return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, abpClaimsPrincipal); 
    } 
 
 
    private async Task<IEnumerable<string>> GetResourcesAsync(ExtensionGrantContext context, ImmutableArray<string> scopes) 
    { 
        var resources = new List<string>(); 
        if (!scopes.Any()) 
        { 
            return resources; 
        } 
 
        await foreach (var resource in context.HttpContext.RequestServices.GetRequiredService<IOpenIddictScopeManager>().ListResourcesAsync(scopes)) 
        { 
            resources.Add(resource); 
        } 
 
        return resources; 
    } 
} 

I noticed the scope of this token is a bit limited. Could we look into adding more scope to it? This way, we can ensure it meets all our needs more effectively. Thanks for considering this!

yes @maliming, pls check your mail

hi @maliming, do you have any ideas?

76 kayıttan 61 ile 70 arası gösteriliyor.
Made with ❤️ on ABP v8.2.0-preview Updated on Mart 25, 2024, 15:11