Activities of "liangshiwei"

it looks like a problem; I will check it. anyway your ticket was refunded.

Hi,

I can reproduce the problem, we will fix it in the next patch version.

your ticket was refunded.

Here is the temporary solution

 public sealed class MyWebAuthenticator
 {
     /// <summary>
     /// Begin an authentication flow by navigating to the specified url and waiting for a callback/redirect to the callbackUrl scheme.
     /// </summary>
     /// <param name="authorizeUri">Url to navigate to, beginning the authentication flow.</param>
     /// <param name="callbackUri">Expected callback url that the navigation flow will eventually redirect to.</param>
     /// <returns>Returns a result parsed out from the callback url.</returns>
     public static Task<WebAuthenticatorResult> AuthenticateAsync(Uri authorizeUri, Uri callbackUri) =>
         Instance.Authenticate(authorizeUri, callbackUri);

     private static readonly MyWebAuthenticator Instance = new MyWebAuthenticator();

     private Dictionary<string, TaskCompletionSource<Uri>> tasks = new Dictionary<string, TaskCompletionSource<Uri>>();

     private MyWebAuthenticator()
     {
         Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().Activated += CurrentAppInstance_Activated;
     }

     [System.Runtime.CompilerServices.ModuleInitializer]
     internal static void Init()
     {
         try
         {
             OnAppCreation();
         }
         catch (Exception ex)
         {
             System.Diagnostics.Trace.WriteLine("WinUIEx: Failed to initialize the WebAuthenticator: " + ex.Message,
                 "WinUIEx");
         }
     }

     private static bool IsUriProtocolDeclared(string scheme)
     {
         if (global::Windows.ApplicationModel.Package.Current is null)
             return false;
         var docPath = Path.Combine(global::Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
             "AppxManifest.xml");
         var doc = XDocument.Load(docPath, LoadOptions.None);
         var reader = doc.CreateReader();
         var namespaceManager = new XmlNamespaceManager(reader.NameTable);
         namespaceManager.AddNamespace("x", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
         namespaceManager.AddNamespace("uap", "http://schemas.microsoft.com/appx/manifest/uap/windows10");

         // Check if the protocol was declared
         var decl = doc.Root?.XPathSelectElements(
             $"//uap:Extension[@Category='windows.protocol']/uap:Protocol[@Name='{scheme}']", namespaceManager);

         return decl != null && decl.Any();
     }

     private static System.Collections.Specialized.NameValueCollection? GetState(
         Microsoft.Windows.AppLifecycle.AppActivationArguments activatedEventArgs)
     {
         if (activatedEventArgs.Kind == Microsoft.Windows.AppLifecycle.ExtendedActivationKind.Protocol &&
             activatedEventArgs.Data is IProtocolActivatedEventArgs protocolArgs)
         {
             return GetState(protocolArgs);
         }

         return null;
     }

     private static NameValueCollection? GetState(IProtocolActivatedEventArgs protocolArgs)
     {
         NameValueCollection? vals = null;
         try
         {
             vals = System.Web.HttpUtility.ParseQueryString(protocolArgs.Uri.Query);
         }
         catch { }

         try
         {
             if (vals is null || !(vals["state"] is string))
             {
                 var fragment = protocolArgs.Uri.Fragment;
                 if (fragment.StartsWith("#"))
                 {
                     fragment = fragment.Substring(1);
                 }

                 vals = System.Web.HttpUtility.ParseQueryString(fragment);
             }
         }
         catch { }

         if (vals != null && vals["state"] is string state)
         {
             var vals2 = System.Web.HttpUtility.ParseQueryString(state);
             // Some services doesn't like & encoded state parameters, and breaks them out separately.
             // In that case copy over the important values
             if (vals.AllKeys.Contains("appInstanceId") && !vals2.AllKeys.Contains("appInstanceId"))
                 vals2.Add("appInstanceId", vals["appInstanceId"]);
             if (vals.AllKeys.Contains("signinId") && !vals2.AllKeys.Contains("signinId"))
                 vals2.Add("signinId", vals["signinId"]);
             return vals2;
         }

         return null;
     }

     private static void OnAppCreation()
     {
         var activatedEventArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent()?.GetActivatedEventArgs();
         if (activatedEventArgs is null)
             return;
         var state = GetState(activatedEventArgs);
         if (state is not null && state["appInstanceId"] is string id && state["signinId"] is string signinId &&
             !string.IsNullOrEmpty(signinId))
         {
             var instance = Microsoft.Windows.AppLifecycle.AppInstance.GetInstances().Where(i => i.Key == id)
                 .FirstOrDefault();

             if (instance is not null && !instance.IsCurrent)
             {
                 // Redirect to correct instance and close this one
                 instance.RedirectActivationToAsync(activatedEventArgs).AsTask().Wait();
                 System.Diagnostics.Process.GetCurrentProcess().Kill();
             }
         }
         else
         {
             var thisInstance = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent();
             if (string.IsNullOrEmpty(thisInstance.Key))
             {
                 Microsoft.Windows.AppLifecycle.AppInstance.FindOrRegisterForKey(Guid.NewGuid().ToString());
             }
         }
     }

     private void CurrentAppInstance_Activated(object? sender, Microsoft.Windows.AppLifecycle.AppActivationArguments e)
     {
         if (e.Kind == Microsoft.Windows.AppLifecycle.ExtendedActivationKind.Protocol)
         {
             if (e.Data is IProtocolActivatedEventArgs protocolArgs)
             {
                 var vals = GetState(protocolArgs);
                 if (vals is not null && vals["signinId"] is string signinId)
                 {
                     ResumeSignin(protocolArgs.Uri, signinId);
                 }
             }
         }
     }

     private void ResumeSignin(Uri callbackUri, string signinId)
     {
         if (signinId != null && tasks.ContainsKey(signinId))
         {
             var task = tasks[signinId];
             tasks.Remove(signinId);
             task.TrySetResult(callbackUri);
         }
     }

     private async Task<WebAuthenticatorResult> Authenticate(Uri authorizeUri, Uri callbackUri)
     {
         if (global::Windows.ApplicationModel.Package.Current is null)
         {
             throw new InvalidOperationException("The WebAuthenticator requires a packaged app with an AppxManifest");
         }

         var scheme = callbackUri.Scheme;
         if(scheme == "https")
         {
             scheme = callbackUri.AbsolutePath.Substring(callbackUri.AbsolutePath.LastIndexOf('/') + 1);
         }

         if (!IsUriProtocolDeclared(scheme))
         {
             throw new InvalidOperationException(
                 $"The URI Scheme {callbackUri.Scheme} is not declared in AppxManifest.xml");
         }

         var g = Guid.NewGuid();
         UriBuilder b = new UriBuilder(authorizeUri);

         var query = System.Web.HttpUtility.ParseQueryString(authorizeUri.Query);
         var state = $"appInstanceId={Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().Key}&signinId={g}";
         if (query["state"] is string oldstate && !string.IsNullOrEmpty(oldstate))
         {
             // Encode the state parameter
             state += "&state=" + System.Web.HttpUtility.UrlEncode(oldstate);
         }

         query["state"] = state;
         b.Query = query.ToString();
         authorizeUri = b.Uri;

         var tcs = new TaskCompletionSource<Uri>();
         var process = new System.Diagnostics.Process();
         process.StartInfo.FileName = "rundll32.exe";
         process.StartInfo.Arguments = "url.dll,FileProtocolHandler " + authorizeUri.ToString();
         process.StartInfo.UseShellExecute = true;
         process.Start();
         tasks.Add(g.ToString(), tcs);
         var uri = await tcs.Task.ConfigureAwait(false);
         return new WebAuthenticatorResult(uri);
     }
 }

public class MyMauiAuthenticationBrowser : IBrowser, ITransientDependency
{
    public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
    {
        try
        {
            WebAuthenticatorResult result = null;
            var webAuthenticatorOptions = new WebAuthenticatorOptions
            {
                Url = new Uri(options.StartUrl),
                CallbackUrl = new Uri(options.EndUrl),
                PrefersEphemeralWebBrowserSession = true
            };

#if WINDOWS
        result =
await Platforms.Windows.MyWebAuthenticator.AuthenticateAsync(webAuthenticatorOptions.Url, webAuthenticatorOptions.CallbackUrl);
#else
            result = await WebAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions
            {
                Url = new Uri(options.StartUrl),
                CallbackUrl = new Uri(options.EndUrl),
                PrefersEphemeralWebBrowserSession = true
            });
#endif


            return new BrowserResult
            {
                Response = ToRawIdentityUrl(options.EndUrl, result)
            };
        }
        catch (TaskCanceledException)
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.UserCancel
            };
        }
        catch (Exception ex)
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.UnknownError,
                Error = ex.ToString()
            };
        }
    }

    private static string ToRawIdentityUrl(string redirectUrl, WebAuthenticatorResult result)
    {
        if (DeviceInfo.Platform == DevicePlatform.WinUI)
        {
            var parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}");
            var modifiedParameters = parameters.ToList();

            var stateParameter = modifiedParameters
                .FirstOrDefault(p => p.StartsWith("state", StringComparison.OrdinalIgnoreCase));

            if (!string.IsNullOrWhiteSpace(stateParameter))
            {
                // Remove the state key added by WebAuthenticator that includes appInstanceId
                modifiedParameters = modifiedParameters
                    .Where(p => !p.StartsWith("state", StringComparison.OrdinalIgnoreCase)).ToList();

                stateParameter = System.Web.HttpUtility.UrlDecode(stateParameter).Split('&').Last();
                modifiedParameters.Add(stateParameter);
            }

            var values = string.Join("&", modifiedParameters);
            return $"{redirectUrl}#{values}";
        }
        else
        {
            var parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}");
            var values = string.Join("&", parameters);

            return $"{redirectUrl}#{values}";
        }
    }
}
switch (configuration["OAuthConfig:GrantType"])
{
    case "password":
        context.Services.AddSingleton<IExternalAuthService, PasswordFlowExternalAuthService>();
        var authServiceClientBuild = context.Services.AddHttpClient(PasswordFlowExternalAuthService.HttpClientName);
#if DEBUG
        authServiceClientBuild.ConfigurePrimaryHttpMessageHandler(GetInsecureHandler);
#endif
        break;
    case "code":
        context.Services.AddSingleton<IExternalAuthService, CodeFlowExternalAuthService>();
        Configure<OidcClientOptions>(configuration.GetSection("OAuthConfig"));

        context.Services.AddTransient<OidcClient>(sp =>
        {
            var options = sp.GetRequiredService<IOptions<OidcClientOptions>>().Value;
            options.Browser = sp.GetRequiredService<MyMauiAuthenticationBrowser>(); // change to MyMauiAuthenticationBrowser

#if DEBUG
            options.BackchannelHandler = GetInsecureHandler();
#endif

            return new OidcClient(options);
        });
        break;
}

Hi,

yes ,you need to add some dependency.

add Volo.Abp.PermissionManagement.Domain package and module dependency

microservice solution it should create the database automatically.

yes, the microservices will create database.

No migrations were applied. The database is already up to date. When I went to the database this is what I see , only the migration history table gets created when the code is getting built :

I guess there are no db migrations files?

you can create it manually

dotnet ef migrations add Initial -c ....

Hi

Here is ABP how to check connection strings https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/ConnectionStrings/SqlServerConnectionStringChecker.cs#L10

The error is a result of pushing the Check button:

could you share the full logs? thanks.

okay, i will check it

Hi,

after my check,you can use IPermissionManager without any problem

Hi,

I guess these databases do not exist yet. You need to run dbmigrator to create them

Hi see https://abp.io/docs/latest/framework/architecture/modularity/extending/module-entity-extensions

view it in another tab in create tenant Modal

you need to override the CreateModalModel

move these code to a new tab

you can download saas module to get CreateModalModel page code

Here is the document about how to override page. https://abp.io/docs/latest/framework/ui/mvc-razor-pages/customization-user-interface

Hi,

They are using RemotePermissionChecker https://github.com/abpframework/abp/blob/rel-8.3/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs#L8

you can override it.

Showing 1 to 10 of 5597 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 18, 2024, 12:46