Laden...
Avatar #avatar-4078.jpg
emuuu myCSharp.de - Member
Ingenieurinformatiker Dabei seit 04.02.2011 286 Beiträge
Benutzerbeschreibung

Forenbeiträge von emuuu Ingesamt 286 Beiträge

04.10.2023 - 12:01 Uhr

Moin zusammen,

habe aktuell die Situation, dass ich ich verschiedenste IEnumerables nutzerseitig filtern lassen möchte (konkret geht es um nen Blazor component der für bereits geladene IEnumerables eine zusätzliche Filter-Funktion bereitstellt).

Nix kompliziertes nur ein bisschen Linq, wobei ich eben die Möglichkeit möchte das Filtern etwas googlelike zu gestalten. Sprich Wenn etwas in Anführungszeichen geschrieben wird, wird nach dem ganzen Text gesucht, andernfalls wird nach jedem einzelnen Wort gesucht, wenn etwas mit % beginnt oder endet wird nach Contains anstatt Equal gesucht etc.

Technisch alles nichts besonders und relativ einfach umzusetzen, aber eben ein wenig Handarbeit. Da ich verschiedene Objekte durchsuchen, will war die Idee eine Helper Library zu schreiben die generics aufnimmt und einfach jede Property vom Typ string durchsucht (oder eben die Properties die explizit eingeschlossen/ausgeschlossen sind).

Die eigentliche Frage daher, bevor ich mich jetzt selbst hinsetze und was zusammenschreibe: Kennt Ihr irgend ein package, was das wie beschrieben oder so ähnlich bereits kann?

Finde online leider wenig dazu bzw. eine endlose Fülle an Seiten die einem erklären wie das technisch grundsätzlich ginge in der die von mir gesuchten Ergebnisse wohl untergehen.

Beste Grüße

Timm

13.05.2022 - 09:18 Uhr

Hab gerade festgestellt, dass MultipartFormDataContent auch IDisposable implementiert.
So funktioniert es jetzt:


   async Task FetchAndUploadFiles()
   {
      var files = await GetFileListFromSomewhere();
      using(var formData = await _iServiceA.BuildFormData(files))
     {
        await _iServiceB.UploadFormData(formData);
     }
     //delete files
   }

Schätze ich hab in meiner ersten Implementierung die einzelnen FileStreams irgendwie squishy gehandled.

13.05.2022 - 08:54 Uhr

Moin zusammen,

hab mal eine Frage die ein bisschen ins Verständnis von Tasks geht:
(Vereinfachte) Ausgangslage: Hab eine List<string> die zu verschiedenen Dateien führen, diese sollen in einen MultipartFormDataContent gepackt und dann via httpclient.PostAsynch hochgeschickt werden und danach gelöscht werden.
Von der Struktur her in etwa so:


interface IServiceA
{
   Task<MultipartFormDataContent> BuildFormData(IEnumerable<string> filePaths);
}

interface IServiceB
{
   Task UploadFormData(MultipartFormDataContent formData);
}

class ServiceC
{
   async Task FetchAndUploadFiles()
   {
      var files = await GetFileListFromSomewhere();
      var formData = await _iServiceA.BuildFormData(files);
      await _iServiceB.UploadFormData(formData);
   }
}

Hier ist jetzt die Frage wie der beste Weg ist dies anzugehen:
Wenn ich das File.Delete direkt hinter den UploadFormData() packe sind die Dateien natürlich vom Prozess noch blockiert.
Für eine einzelne Datei würde ich einfach ein using-Statement für den FileStream um die Methoden setzen und danach löschen.
Wenn ich allerdings X Dateien habe ist mir nicht ganz klar wie hier der saubere weg aussieht.

Beste Grüße
emuuu

23.09.2021 - 16:22 Uhr

Moin zusammen,

ich habe ein kleines Problem bzgl der Serialisierung in eine XML Datei:
Konkret habe ich die Klasse TestProbe (mit einer inneliegenden Baumstruktur die hierfür aber egal ist). Diese möchte ich in eine XML-Datei konvertieren die ein Zielprogramm einlesen kann.
Das Zielprogramm verlangt nun, dass das Root-Element TestProbe mit einigen Namespaces daher kommt:


<TESTPROBE xmlns:cm="http://www.sparkworks.com/Common-Measurement-xml" xmlns:sl="http://www.sparkworks.com/TestProbe-Language-xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sparkworks.com/TestProbe-Database-xml">
</TESTPROBE>

Inhaltlich haben die Namespaces für meinen Teil des Systems keinerlei Relevant (ich könnte also im Prinzip im Convert am Ende die Datei um die Textpassagen ergänzen), möchte das aber natürlich sauber lösen.
Und ganz im Ernst: Ich habe keine Ahnung wie. Ich recherchiere nun den halben Tag an XML-Attributen herum (zugegeben nicht mein Fachgebiet) und kriege es einfach nicht hin, dass der Konverter genau diese genau so ins Element schreibt.


	[XmlRoot(ElementName = "TESTPROBE", Namespace = "http://www.sparkworks.com/TestProbe-Database-xml")]
	public class TestProbe
	{
	//...
	}

Der Namespace (sowie die XMLSchema-Instance) werden auch problemlos eingefügt aber eben die LocalNames ("xmlns:cm", usw) nicht.
Ich habe es unter anderem schon mit diesem Ansatz versucht:


		[XmlAttribute(AttributeName = "cm", Namespace = "xmlns")]
		public string CommonMeasurement{ get; set; }

Leider ohne Erfolg.
Bin für jeden Rat dankbar, wobei mir schon ein paar Stichworte in die richtige Richtung helfen würden.

Beste Grüße
emuuu

07.01.2021 - 09:15 Uhr

In der Praxis findet aber HATEOAS kaum Anwendung, weil es schon auch große Nachteile hat:

Super erstmal danke für die Hinweise. Hab mir bewusst ein kleines Projekt gesucht, wo eine mögliche Überkomplexität, am Ende keine Beine bricht. Ich will vor allem ein Gefühl für Nutzen und Aufwand kriegen, um im Zweifel dann dafür oder dagegen argumentieren zu können.

Ansonsten weiß ich nicht, was Du mit Geschäftslogik meinst; denn in de Links wird nur der State übertragen.

Damit meine ich ganz platt in welcher Form die Informationen innerhalb der API weitergereicht / zusammengetragen werden.
Wenn ich z.B. in einer response die Links von drei verschiedenen Controllern habe und bei einem nested object kann der user aufgrund der authorization editieren, bei zweien deleten und die restlichen nur get.
Ich weiß momentan nicht an welcher Stelle in der API ich die Kenntnis über alle möglichen Links + die Authorization zusammentragen würde.

Gib Deine API Klassen niemans ein Suffix wie DTO, sondern arbeite einfach mit einem spezifischen Namen wie "Product" und einem sauberen Namespace.

Wie siehts da mit z.B. create- und update-klassen aus? ProductCreate, ProductUpdate?

Wenn ich für unterschiedliche authorization unterschiedliche Details ausgebe (bsp Kunde kann nur Name, Preis, etc sehen, Produzent die Parts, Teilenummer, usw.):
Ich verwende dafür unterschiedliche Klassen Product, ProductForManager. Wie verträgt sich das mit doc discovery?

06.01.2021 - 15:42 Uhr

Guten Tag zusammen,

wie der Titel schon sagt beschäftige ich mich momentan mit authorization aware hateoas (tl;dr; anstatt alle möglichen transitions gibt der server nur die im aktuell authorization context gültigen transitions zurück -> Kunde kann Produkte abfragen aber nicht updaten)
und würde das in einem neuen Projekt gerne anwenden. Das Grundprinzip ist ja relativ simpel.
Meine Frage wäre nun, ob wer von euch damit schon Erfahrungen hat und optimalerweise irgendwelche examples hat / kennt.

Mich interessiert dabei vor allem die Projektstruktur und Zugriffsebenen:
Die Links kennt imho nur der Controller die Authorization hingegen liegt um untergeordneten business layer.

Und wie sieht es mit nested objects aus? Wenn ich bsp folgendes Dto habe:


public class ProductDto
{
   public int Id {get;set;}

   [..]

   public IEnumerable<PartDto> Parts {get;set;}
}

Mir ist noch nicht ganz klar, wie ich die Information über die möglichen transitions (die beim PartDto z.B. aus einem anderen Controller kommen als für ProductDto aufgerufen wurde) in die Geschäftslogik und wieder zurück kriege (ohne gegen Konventionen zu verstoßen).

Natürlich wird es hier nicht den einen richtigen Weg geben und es ist immer von den weiteren Anforderungen anhängig. Aber mir fehlts dahingehend momentan an einem Grundgerüst, das man weiterentwickeln kann.

Beste Grüße
emuuu

10.11.2020 - 11:24 Uhr

Wundert mich, dass es noch keine News dazu gab, darum hier in aller Kürze:
Heute launched .NET 5 auf der .NET Conf 2020 :]

10.11.2020 - 10:43 Uhr

Für eine "richtige" Cross-Plattform-UI soll MAUI kommen, aber das steht noch aus.
Xamarin kann nach meinem letzten Stand nur mobile Geräte, keinen Desktop und wird nach .NET 6 auch recht bald sein Ende finden, da es ja durch MAUI abgelöst werden soll.

Xamarin kann mit Forms iOS, macOS, Android & UWP ist also stand jetzt schon absolut Cross-Plattform fähig. Du kannst damit quasi auf alles aktuelle außer Linux & exotische Smartphone OS (e.g. HarmonyOS von Huawei).
Habe eine App die ich problemlos auf einem Windows-PC ebenso wie auf einem iPhone deployen kann.

MAUI löst Xamarin auch imho nicht ab sondern ist ein rebranding (Microsoft hat Xamarin gekauft und schließt damit quasi die Einbindung in die eigene Produktfamilie ab).
Unter der Haube wird sich nicht allzu viel ändern.

10.11.2020 - 10:03 Uhr

ganz schön freche antwort wenn man bedenkt das man dir helfen will. ich denke du kannst es einfach nicht kapieren oder willst es nicht kapieren.

Ich empfinde deine Antworten eher als extrem herablassend und mit gefährlichem Halbwissen gespickt.

Kilo hat 10 bytes also heisst es ausgesprochen 2 hoch 10 Bytes = 1024 Bytes

Das ist vollkommener Quatsch. Man sagt zu 210 Bytes wie ayykaramba schon richtig gesagt hat einfach umgangssprachlich Kilo, weil 103 am nächsten dran an 2^10 ist. Und die SI-Präfixe waren damals einfach extrem verbreitet und daher hat sich das durchgesetzt.

Mit dem Aufkommen der TB-Festplatteten haben die Hersteller sich das direkt zu nutze gemacht und bei einer 1 TB-HDD nur 1000 GB anstatt 1024 GB reingepackt.

27.10.2020 - 09:41 Uhr

Moin zusammen,

bin gerade über dieses schöne Repo zum Erstellen eines Widgets, welche die Corona-Fallzahlen + die Inzidenz für den Aufenthaltsort anzeigt, gestolpert:
incidens_and_newcases.js

Ihr benötigt dafür die App Scriptable (eine genaue Anleitung ist im gist enthalten)

Ich kenne mich mit Android-Widgets nicht aus, aber da das Script in js ist, sollte es sich relativ leicht für Android anpassen lassen.

Beste Grüße
emuuu

Edit:
Hier ist der Original-Code der auch zahlreiche Forks mit verschiedenen, fertigen Varianten (mit Bildern) auflistet.

15.09.2020 - 18:01 Uhr

Auch wenn der Client zB 10.000 Einträge will, würde man nur 1000 zurück geben.
Macht man allgemein beim API Design so (auch bei REST und Co..).

Im Allgemeinen ist mir das klar, aber hierbei geht es ja um eine Klassenbibliothek, die man als Teil eines Projektes nutzen soll.
Sollte ich da nicht eher dem Anwender überlassen wie er die Pagination in seinem Service limitiert? Es ist ja eher ein Tool, das noch konfiguriert / benutzt werden soll als eine fertige Lösung.

15.09.2020 - 17:18 Uhr

Hier mal die Variante mit Filter / Sort via Linq:


public virtual async Task<IList<TEntity>> GetAll<TProperty>(Expression<Func<TEntity, bool>> filter, Expression<Func<TEntity, TProperty>> sorting, int? page = null, int? pageSize = null)
		{
			IList<TEntity> result = await Collection
				.AsQueryable()
				.Where(filter)
				.OrderBy(sorting)
				.ToListAsync().ConfigureAwait(false);

			if(page.HasValue && pageSize.HasValue)
            {
				if (page < 1)
				{
					page = 1;
				}
				if (pageSize < 1)
				{
					pageSize = 1;
				}

				result = result
				.Skip((page.Value - 1) * pageSize.Value)
				.Take(pageSize.Value)
				.ToList();
			}
			return result;
		}

TProperty wird benötigt, da TKey auf eine contravariant wäre (da bereits verwendet).

Spricht was gegen den Ansatz? (ThenBy würde ich in einem separaten overload implementieren)

Wie sieht es eigentlich in Richtung best practices aus, was die parameter angeht? Sollte ich lieber für jede Variante nen eigenen overload erstellen oder so wie bisher alles gleichzeitig aufnehmen und nen null-Value einfach handlen?

15.09.2020 - 12:39 Uhr

Guten Tag zusammen,

ich hatte hier schon mal mein Mongo repository gepostet für das ich momentan versuche eine Erweiterung zu bauen.

Da der Service der das Mongo repository anspricht selbst nur eine Zwischenschicht ist die via gRPC angesprochen wird brauche ich eine Möglichkeit FilterDefinitions vom gRPC client an den Service zu übertragen.
Iirc ist es kaum möglich Builder<FooBarClass>.Filter.Eq("Foo", "Bar") direkt im protobuf zu definieren.

Ich müsste also eine Abstraktion für Filterregeln erstellen und diese dann übertragen, also sowas in die Richtung:


message Filter {
  string field = 1;
  repeated string values = 2;
  string operator = 3;
  bool strongRequired = 4;
}

message FilteredRequest {
  repeated Filter filters = 1;
}

Da ich das Rad nicht unbedingt neu erfinden will wäre meine Frage:
Welchen Ansatz würdet ihr nehmen? Oder gibt es bereits was Ähnliches, an das man anknüpfen könnte?
Vllt verwende ich nur die falschen Suchbegriffe aber für den konkreten Fall finde ich bisher so gut wie gar nix.

Beste Grüße
emuuu

P.s. ich habe eine funktionierende Lösung in der ich auf client Seite einen Builder erstelle, den in einen json string umwandle, diesen übertrage und das ganze auf der anderen Seite mit JsonFilterDefinition<FooBarClass> verwende. Finde ich aber irgendwie unelegant.

08.09.2020 - 22:44 Uhr
  • Bei CosmosDB erhälst Du eine Garantie auf eine Leistung (die genannten Request Units).
  • Bei MongoDB Atlas erhälst Du die freie Verfügung über Ressourcen.

Der Teil ist mir bewusst und wenn ich sage ich hab mich noch nicht so sehr beschäftigt, dann meine ich vor allem dass die RUs für mich noch etwas mystisch sind.

Ich habe aktuell einen einzigen MSSQL der insgesamt knapp 5gb hat und ca 30k requests pro Tag frisst, lokal gehostet in einem Swarm. Also nix Großes.

Und die möchte ich eben der Reihe nach auskoppeln und suche gerade nach einer noSQL-Lösung.

08.09.2020 - 19:55 Uhr

Guten Tag zusammen,

wollte man nach euren Erfahrungen mit CosmosDB fragen, vor allem in Bezug auf Kosteneffizienz.
Habe jetzt mal eine DB als Test im Free-Tier erstellt und bin etwas irritiert über die Kosten:
Eine Collection mit einem Document, dass eine Größe von 65 kB hat -> 1,36$ pro Tag.

Ich hab mich jetzt noch nicht mit dem weiteren pricing beschäftigt, aber wenn eine Test DB in der ich wirklich nicht viel gemacht hat mir direkt ~40 $ / Monat um die Ohren haut, bin ich direkt nicht sehr motiviert für mehr. Oder verstehe ich die Verwendung oder die Vorteile von CosmosDB falsch? (Azure sagt sie haben keine Optimierungsvorschläge).

Ich meine wenn ich das mit MongoDB Atlas vergleiche zahle ich für nen Cluster mit sharedCPU/RAM und 2GB storage 9$ /month.

Finde den Unterschied schon sehr gravierend. Oder hat CosmosDB einfach irgendwelche überragenden perks die ich nicht hoch genug wertschätze?

Beste Grüße
emuuu

03.09.2020 - 12:08 Uhr

Super, danke schon mal für das Feedback, gerade in Bezug auf Konventionen, da ich da noch nicht so firm bin.

Die eigenen commit messages, mache ich immer auf Englisch, allerdings habe ich den initial commit über das GitHub-plugin von VS erstellt, vermute dass das auf DE localed ist. Da muss ich mir nochmal die Einstellungen anschauen.

Feedback:

  • Deine Methoden sind alle Fire-and-Forget aufgebaut. Der Verwender hat keine Chance die Results der MongoDB Operationen zu erhalten.

Meinst du damit, dass ich await Collection.... direkt zurückgebe?

03.09.2020 - 11:22 Uhr

Guten Morgen zusammen,

ich habe für meine Anwendung ein einfaches (MongoDB-)Repository erstellt, dass CRUD liefert und beliebig erweitert werden kann.
Für mich ist Ziel des Ganzen, dass ich in einer Microservice-Umgebung möglichst unkompliziert einen neuen Service erstellen kann, der eine einzige Enity verwaltet erstellen kann.

MongoRepository
Kritik, Anregungen und vor allem Verbesserungsvorschläge sind willkommen.

Beste Grüße
emuuu

24.08.2020 - 16:17 Uhr

Auch schon davor, oder erst jetzt nach Deinem Edit um 16:07 Uhr?
Problem nun mit der richtigen Krestel-Config gelöst?

Jop das Problem besteht wenn ich in der Program.cs im CreateHostBuilder .UseKestrel verwende.
Wenn ich stattdessen .ConfigureKestrel (wie im edit) verwende, funktioniert es.

24.08.2020 - 16:13 Uhr

Wie sieht die originale Startup.Configure() Methode aus?

Das UseKestrel kommt bei mir aus der Program.cs

Welche ASP.NET Core Version hast Du denn?

3.1

Weil Kestrel wird in den neueren Versionen über den Host Builder konfiguriert und nicht über Configure().

Da hab ichs auch drin, aber eben mit webBuilder.UseKestrel() anstatt .ConfigureKestrel


        private static IHostBuilder CreateHostBuilder(IConfigurationRoot configuration, string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
            //..
            })

24.08.2020 - 15:54 Uhr

Die Anfrage an den grpc-Server dauert so lang:


//2000ms:
await client.GetAllToolsAsync(new AllToolsRequest())

Auf der anderen ist der grpc-Server in der Verarbeitung aber recht zügig:


//22ms:
public override async Task<MultipleToolReply> GetAllTools(AllToolsRequest request, ServerCallContext context)
{
//..
}

Was also so lang dauert ist die reine Übertragung. Es muss etwas mit .UseKestrel zu tun haben.
Wen ich den Teil komplett rausnehme kriege ich eine vernünftige ResponseTime

Update:
Ok, irgendwie ist UseKestrel broke.
Wenn ich


   .UseKestrel(options =>
   {
      options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
      {
         listenOptions.Protocols = HttpProtocols.Http2;
         listenOptions.UseHttps($"/etc/certs/{serviceName}.p12", serviceName);
      });
   })

durch


   .ConfigureKestrel(options =>
   {
      options.ListenAnyIP(ports.grpcPort, o =>
      {
         o.Protocols = HttpProtocols.Http2;
         o.UseHttps($"/etc/certs/{serviceName}.p12", serviceName);
      });
   })

ersetze, funktioniert es problemlos

24.08.2020 - 15:40 Uhr

Guten Tag zusammen,

ich habe ein Problem mit gRPC in folgendem Setup:
Api-Gateway <-> gRPC-Server <-> Azure CosmosDB

Die API sowie den gRPC-Server lasse ich beide auf localhost laufen (mit tls). Das Problem nun: Selbst wenn beides Services hot sind dauert eine GetAll-Response (377 Byte response body) 2,08 Sekunden.

Hab jetzt die Dauer der einzelnen Schritte analysiert und hier die Bremse idenzifiziert:


        public async Task<List<ToolDto>> GetAll()
        {
            return await GrpcCallerService.CallService(_urls.GrpcTools, async channel =>
            {
                var client = new ToolStore.ToolStoreClient(channel);
                var response = await client.GetAllToolsAsync(new AllToolsRequest()); //dauert ~2000ms
                return response.Tools.Select(x => _mapper.Map<ToolDto>(x)).ToList();
            });
        }

Auf der anderen Seite von AllToolsRequest antwortet braucht der gRPC-Server allerdings nur ~22ms zum verarbeiten:


        public override async Task<MultipleToolReply> GetAllTools(AllToolsRequest request, ServerCallContext context)
        {
            try
            {
                var tools = await _toolRepository.GetAll();

                var result = new MultipleToolReply();
                result.Tools.AddRange(tools.Select(x => _mapper.Map<ToolReply>(x)));
                return result;
            }
            catch (Exception ex)
            {
                throw new RpcException(new Status(StatusCode.Internal, ex.Message));
            }
        }

Das Problem muss im gRPC-Server verortet sein, da ich bei abrufen mit 3rd party tools wie bloomRPC auf die gleichen response Zeiten komme.
Sprich irgendwas in der Übertragung ist extrem langsam. Habt ihr irgendeine Idee woran das liegen kann?

gRPC-Server:
Program.cs


                .UseKestrel(options =>
                {
                    var ports = GetDefinedPorts(configuration);

                    var serviceName = Environment.GetEnvironmentVariable("service_name") ?? "localhost";

                    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
                    {
                        listenOptions.Protocols = HttpProtocols.Http2;
                        listenOptions.UseHttps($"/etc/certs/{serviceName}.p12", serviceName);
                    });
                })

Startup.cs


            services.AddGrpc();

            //...
            app.UseEndpoints(endpoints =>
            {
                GrpcEndpointRouteBuilderExtensions.MapGrpcService<ToolService>(endpoints);
            });

Beste Grüße
emuuu

21.08.2020 - 11:05 Uhr

Kleines Update dazu:
Es gibt von Cloudflare ein Docker image für eine CA:
GitHub
DockerHub

Die platziere ich im gleichen Docker stack und vertraue ihr mit allen Services. Für die Microservices schreibe ich ins Dockerfile ein Script, dass im Volume nach einem Zertifikat sucht und andernfalls eins beim CA-Service anfragt und in die ins Volume schreibt.

Weder die CA noch die Microservices sind außerhalb des stack-networks erreichbar.

19.08.2020 - 23:44 Uhr

Guten Abend zusammen,

ich bin gerade über was hübsches für Blazor gestolpert:
BlazorTransitionableRoute
nuget package

blazor transition pages

07.08.2020 - 17:51 Uhr

Guten Tag zusammen,

ich bastle gerade an einem IoT-Projekt bei dem ich auf einem RaspberryPi eine Blazor-App auf localhost laufen lassen möchte.

Die Frage ist nun: Ob und wie kann ich die Nutzung vom weiterer Hardware am raspi unterstützen. Beispielsweise die Anbindung von einem NFC/RFID-Leser.

Also zwei Szenarien:

  1. Klick in Blazor-App -> Aktiviere / Lese NFC -> result an die App
  2. NFC-Leser findet was Lesbares -> push an die App

Vor alle zweites Szenario fände ich interessanter, aber vermutlich auch komplexer.
Habt ihr da Erfahrungen / Erkenntnisse?

Beste Grüße
emuuu

28.07.2020 - 15:49 Uhr

Es ist halt schon lustig, dass wirklich der LETZTE Eintrag vor deinem dir exakt die Antwort liefert die du brauchst..

So in Richtung Regeln und Forensuche........

Und wenn dir das als Antwort nicht präzise genug ist: Du sagst so gut wie gar nichts über deine Umgebung bzw. was du machen möchtest.
C# ist in erster Linie nur eine Sprache. Ohne ein Framework bzw eine Plattform zu bestimmen ist es mehr oder minder unmöglich dir einen Lösungsansatz zu liefern.

Da du in Webtechnologien gepostet hast ist vermutlich ASP.NET Core 3 dein weg und damit wäre AddOpenIdConnect() dein Weg.

Beste Grüße emuuu

24.07.2020 - 14:55 Uhr

Ist das vielleicht der Redirect zum Identity Provider?

Jop, ist es aber nicht. Das würde auch aber auch einen anderen Fehler verursachen (invalid client oder so), da der Client jetzt einen anderen Flow verwendet. Wenn sich jemand sich den Redirect gebookmarked hätte, wäre in der Request-URL noch der alte Flow hinterlegt (konkret meine ich das id_token im response type).

24.07.2020 - 13:42 Uhr

Die Meldung ist jetzt schon eine Woche alt, aber GitHub hat seine Arktis-Archivierung abgeschlossen:
GitHub schließt Archivierung im Eis ab

Gilt für alle öffentlichen Repositories und alle Contributors erhalten ein Badge. Habe es jetzt selbst erstmal angezeigt bekommen:

24.07.2020 - 11:57 Uhr

        public static IServiceCollection ConfigureIdentityServices(this IServiceCollection services, IConfigurationRoot configuration)
        {
            var settings = configuration.GetConfiguration<OpenIdConnectOptions>();
            var client = configuration.GetConfiguration<OAuthClient>();

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = settings.SignInScheme;
                options.DefaultScheme = settings.SignInScheme;
                options.DefaultChallengeScheme = settings.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromSeconds(2592000);
                options.Cookie.Name = settings.CookieName;
                options.Cookie.IsEssential = true;
                options.AccessDeniedPath = "/account/accessdenied";
                options.LoginPath = "/account/login";
                options.SlidingExpiration = true;
            })
            .AddAutomaticTokenManagement()
            .AddOpenIdConnect(settings.AuthenticationScheme, options =>
            {
                options.Authority = settings.Authority;
                options.RequireHttpsMetadata = settings.RequireHttpsMetadata;

                options.CallbackPath = new PathString(settings.CallbackPath);
                options.SignedOutCallbackPath = new PathString(settings.SignedOutCallbackPath);
                options.RemoteSignOutPath = new PathString(settings.RemoteSignOutPath);
                options.ClientId = client.ClientId;
                options.ClientSecret = client.ClientSecret;
                options.ResponseType = settings.ResponseType;
                options.ResponseMode = settings.ResponseMode;

                foreach (var scope in settings.Scopes)
                {
                    options.Scope.Add(scope);
                }

                options.GetClaimsFromUserInfoEndpoint = settings.GetClaimsFromUserInfoEndpoint;
                options.SaveTokens = settings.SaveTokens;
                options.TokenValidationParameters = settings.TokenParameter;

                options.ClaimActions.MapAllExcept("role", "iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash", "auth_time", "idp", "amr");
                options.ClaimActions.Add(new Helpers.JsonKeyClaimAction(JwtClaimTypes.Role, null, JwtClaimTypes.Role));

                options.UsePkce = settings.UsePkce;
                /*
                 * .netcore2.1 approach
                options.Events.OnRedirectToIdentityProvider = context =>
                {
                    if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                    {
                        var codeVerifier = CryptoRandom.CreateUniqueId(32);

                        context.Properties.Items.Add("code_verifier", codeVerifier);

                        string codeChallenge;
                        using (var sha256 = SHA256.Create())
                        {
                            var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                            codeChallenge = Base64Url.Encode(challengeBytes);
                        }

                        context.ProtocolMessage.Parameters.Add("code_challenge", codeChallenge);
                        context.ProtocolMessage.Parameters.Add("code_challenge_method", "S256");
                    }

                    return Task.CompletedTask;
                };

                options.Events.OnAuthorizationCodeReceived = context =>
                {
                    if (context.TokenEndpointRequest?.GrantType == OpenIdConnectGrantTypes.AuthorizationCode)
                    {
                        if (context.Properties.Items.TryGetValue("code_verifier", out var codeVerifier))
                        {
                            context.TokenEndpointRequest.Parameters.Add("code_verifier", codeVerifier);
                        }
                    }

                    return Task.CompletedTask;
                };
                */
            });

            services.AddHttpClient();
            services.AddSingleton<IDiscoveryCache>(r =>
            {
                var factory = r.GetRequiredService<IHttpClientFactory>();
                return new DiscoveryCache(settings.Authority, () => factory.CreateClient());
            });

            return services;
        }

appsettings.json


  "OpenIdConnect": {
    "AuthenticationScheme": "oidc",
    "SignInScheme": "Cookies",
    "CookieName": "fmid",
    "Authority": "https://login.domain.com",
    "RequireHttpsMetadata": "true",
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath": "/signout-callback-oidc",
    "RemoteSignOutPath": "/signout-oidc",
    "ResponseType": "code",
    "ResponseMode": "form_post",
    "UsePkce": "true",
    "GetClaimsFromUserInfoEndpoint": "true",
    "Prompt": "login",
    "SaveTokens": "true",
    "Scopes": [ "profile", "openid", "offline_access", "api_access" ],
    "TokenParameter": {
      "NameClaimType": "name",
      "RoleClaimType": "role"
    }

appsettings.secret.json


  "OAuthClient": {
    "Issuer": "login.domain.com",
    "ClientId": "idf_web_client",
    "ClientSecret": "change-this-in-production"
  }

24.07.2020 - 11:41 Uhr

3.1, ich weiß auch, dass das mit UsePkce out of the Box funktioniert.

Hab jetzt nur testweise die händische Implementierung nochmal getestet. Das Ergebnis ist bei beiden aber das gleiche.

24.07.2020 - 11:07 Uhr

Die Schwierigkeit die ich dabei habe ist, dass ich aktuell keinen Zugriff auf eine betroffene Umgebung habe.
Bei den beiden die angerufen haben ist es durch manuelle Eingabe der Domain gelöst.

Außerdem dürfte das doch eigentlich nix mit Caching zu tun haben oder?

Ich mein wenn ich das hier in unter AddOpenIdConnection habe, kann es doch eigentlich nicht sein, dass die code challenge bei einigen nicht ausgeführt wird:


                options.Events.OnRedirectToIdentityProvider = context =>
                {
                    if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                    {
                        var codeVerifier = CryptoRandom.CreateUniqueId(32);

                        context.Properties.Items.Add("code_verifier", codeVerifier);

                        string codeChallenge;
                        using (var sha256 = SHA256.Create())
                        {
                            var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                            codeChallenge = Base64Url.Encode(challengeBytes);
                        }

                        context.ProtocolMessage.Parameters.Add("code_challenge", codeChallenge);
                        context.ProtocolMessage.Parameters.Add("code_challenge_method", "S256");
                    }

                    return Task.CompletedTask;
                };

                options.Events.OnAuthorizationCodeReceived = context =>
                {
                    if (context.TokenEndpointRequest?.GrantType == OpenIdConnectGrantTypes.AuthorizationCode)
                    {
                        if (context.Properties.Items.TryGetValue("code_verifier", out var codeVerifier))
                        {
                            context.TokenEndpointRequest.Parameters.Add("code_verifier", codeVerifier);
                        }
                    }

                    return Task.CompletedTask;
                };

Ich habs auch schon auf replicas 1 gesetzt um sicherzustellen, dass nicht irgendwer auf eine alte Version zugreift.
Kann wirklich nicht nachvollziehen woher der Fehler kommen kann.

24.07.2020 - 10:11 Uhr

Guten Morgen zusammen,

ich habe gerade ein etwas weirdes Problem:
Habe meinen IdentityServer vom Hybrid-Flow auf Code-Flow mit PKCE umgestellt. Es funktioniert auch alles soweit.

Allerdings haben einige (wenige) User das Problem, dass wenn Sie die Website über ein Bookmark aufrufen der IdentityServer denen eine invalid request um die Ohren haut (logs sagen code_challenge is missing).

Mein Problem ist, dass ich den Fehler in keiner Weise reproduzieren kann.

Browserdaten löschen hat nichts gebracht, gelöst werden konnte es bisher nur wenn die Website über Eingeben der Domain in der Adresszeile aufgerufen wird. Danach funktionieren auch die Bookmarks wieder (nur eigene Bookmarks nicht Chromes recently used bookmarks)

Habt ihr irgendeine Idee woran das liegen kann?

Beste Grüße
emuuu

07.05.2020 - 10:18 Uhr

Guten Tag zusammen,

ich wollte mal fragen, ob wer von euch Erfahrungen mit Portainer hat und für welchen UseCase ihr das (nicht) empfehlen würdet.

Auf den ersten Blick liefert mir das nur ein hübsches GUI für Cluster und erspart mir ein bisschen CLI. Das wären für mich jetzt beides keine abschließenden Argumente das einzusetzen.

Gibt es da noch sonstige Punkt die dafür/dagegen sprechen?

Beste Grüße
emuuu

21.04.2020 - 09:24 Uhr

Was wäre denn der korrekte Weg um Zertifikate zu erstellen, mit denen sich die Container untereinander vertrauen können?
Wenn ich innerhalb des Swarms z.B. mehrere Services habe die über gRPC miteinander reden und mehrere Gateways die dieses wiederum via https ansprechen?

Ich könnte jedem Service im docker-compose einen festen Network-Alias mitgeben für den ich ein Zertifikat erstelle. Aber wo platziere ich die CA dafür und bringe den Services bei dieser zu vertrauen?

20.04.2020 - 13:20 Uhr

Ok, danke für die Info, habe ich mir schon fast so gedacht - aber Feedback ist da doch hilfreich.

Eine Frage noch zu praktischen Umsetzung: Kann ich einfach ein eigenes Zertifikat erstellen, dem Swarm als Secret mitgeben und dann einfach bei allen relevanten Services einfach folgendes machen:


    environment:
        ASPNETCORE_Kestrel__Certificates__Default__Path: /run/secrets/https-certificate
        ASPNETCORE_Kestrel__Certificates__Default__Password: /run/secrets/https-certificate-password
        ASPNETCORE_URLS: 'https://+;http://+'
        ASPNETCORE_HTTPS_PORT: 443

Oder sollte ich für jeden Service ein eigenes Zertifikat erstellen (wenn eins corrupted wird wären es doch ohnehin alle - da am gleichen Ort hinterlegt)

20.04.2020 - 12:39 Uhr

Guten Tag zusammen,

der Titel beschreibt die Frage ja schon recht gut:
Ich habe einen Webservice (dotnet/core/aspnet) in einem Docker-swarm der via Traefik über https erreichbar ist.

Die Frage ist jetzt einfach: Soll der der Service (Container) selber auch auf HTTPS oder auf HTTP lauschen (also die Verbindung Traefik <-> Service)?
Mir geht es vor allem darum Vor- gegen Nachteile abzuwägen.

Ich sehe hier vor allem eine Abwägung von Performancegewinn (viele kurze Verbindungen -> weniger Handshakes) vs Sicherheitsverlust.
Wobei ich letzteres als gering einschätze, da nur die Verbindung innerhalb des Swarms nicht mehr verschlüsselt ist und mir kein realistisches Szenario einfällt wie das jemand aufmachen könnte.

Wie seht ihr das? Sollte die Kommunikation innerhalb eines Swarms auch (generell) verschlüsselt sein?

P.s. Ich hatte schonmal ein ähnliches Thema, indem es aber eher um die praktische Umsetzung und weniger das Konzept ging.

03.04.2020 - 18:54 Uhr

Dafür gibts den IAuthorizationService

Den verwende ich schon:

var authorizationResult = await _authorizationService.AuthorizeAsync(_user, deviceID, "PatchDevice");

Innerhalb der Service-Klasse habe ich die Patch-Methode mit der ich o.g. aufrufe.

Das Problem ist halt hier der Punkt "DeviceID" für die zweite Requirement bräuchte ich das PatchDocument.

03.04.2020 - 13:46 Uhr

Guten Tag zusammen,

der Titel klingt etwas komplizierter als es eigentlich ist:
Ich möchte eine Policy erstellen die prüft, ob ein PATCH Vorgang erlaubt ist:


            options.AddPolicy("PatchDevice", policy =>
            {
                policy.Requirements.Add(new DeviceAssignedRequirement());
                policy.Requirements.Add(new DeviceAllowedPatchPathRequirement());
            });

Die erste Requirement kontrolliert, ob das Device dem User zugeordnet ist. Der Handler benötigt also die DeviceID (oder direkt das Device object).

Die zweite Requirement kontrolliert, ob path und operation erlaubt sind (z.B. nur Replace auf Path /X & /Y), benötigt also das JsonPatchDocument<DeviceUpdateDto>

Ich sehe momentan zwei Wege:
Entweder es in zwei Policies aufteilen oder eine übergeordnete Klasse schaffen in der für die jeweiligen Requirements alle notwendigen Ressourcen hinterlegt sind.

Gibt es hier noch andere, bessere Wege das umzusetzen?

Beste Grüße
emuuu

30.03.2020 - 14:47 Uhr

Automapper schenkt Dir das nicht. Das musst selbst machen.
AM erstellt statische Expression Trees, die nicht dynamisch erzeugt werden. Das wäre auch zu unperformant.
Wenn Du verschiedene Modelle hast musste halt mit den Nachteilen leben.

Den Vorteil den ich sehe wenn ich Zwischenmappings verwenden würde: Ich hätte für jedes Authorisierungszenario eine Klasse (eine Datei) in der übersichtlich zusammenläuft, wer was sehen kann.

Dafür gibt es IAuthorizationService und Policies.

Dazu hätte ich auch eine Frage:
Ist es legitim in einen AuthorizationHandler z.B. ein Repository zu injecten? Ich denke da vor allem an etwas komplexere Authorisierungszenarien:

Ich habe einen SimCards- und einen MobileDevices-Service. Jede SimCard ist einem MobileDevice zugeordnet, jedes MobileDevice einer Person.

Jetzt möchte Person den PIN der SimCard updaten -> das darf sie nur, wenn ihr das MobileDevice zugeordnet ist, dem die SimCard zugeordnet ist.

Der AuthorizationHandler müsste also selber die MobileDevice-Entity laden und prüfen, ob dort die PersonID mit dem aktuellen UserContext übereinstimmt.

Wäre das vom Vorgehen her legitim?

30.03.2020 - 13:42 Uhr

Höre ich zum ersten Mal, dass man hier verschiedene DTOs verwenden soll. Wo steht das denn?

War auf Stackoverflow in einigen Threads die accepted answer. Ohne dass in den Kommentaren groß dagegen argumentiert wurde.

Ich bin natürlich faul und würde das gerne über Automapper lösen:
Könnte ich mir einfach für alle Authorisierungs-Szenarien ein "Zwischenmapping" erstellen?
Also abhängig vom Zugriff mappe ich die Entity erst auf z.b. auf das PersonForAdminDTO und dann auf das PersonDTO.

Könnte ich z.B. einfach in jede Serviceklasse das einfügen:


private PersonDTO FilterByAuthorization(Person person)
{
   if (_user.IsInRole("Admin"))
   {
      var personForAdminDto = _mapper.Map<PersonForAdminDTO>(person);
      return _mapper.Map<PersonDTO>(personForAdminDto);
   }
   else if 
   {
      //... other
   }
}

Ist in meiner Vorstellung der praktischste Weg alle nicht freigegebenen Felder zu nullen.

30.03.2020 - 09:57 Uhr

Guten Tag zusammen,

der Titel umreißt meine Frage schon relativ klar. Ich habe eine Entity "Person" die mit unterschiedlicher Authorisierung abgerufen werden kann.
Sprich ein Admin kann nur iwelche technischen Daten sehen, AccountManager alles bis auf die technischen Daten usw.

Dem was ich bisher gelesen habe nach, ist der beste Ansatz hierfür verschiedene DTOs zu verwenden:
PersonForAdminDTO, PersonForAccountManagerDTO, PersonForItselfDTO, usw.

Zwei Sachen stören mich daran nur:

  1. Ich müsste den Authorization-Teil der BLL von der Service-Klasse in den Controller schieben, da ich nur hier "problemlos" unterschiedliche Klassen zurückgeben kann
  2. Wie wirkt sich das auf Swagger aus? Sollte ich hier voneinander abgeleitete Klassen oder Interfaces verwenden. Oder ist das für einen produktiven Einsatz von Swagger relativ egal wenn die selbe Route unterschiedliche DTOs zurückgibt?

Beste Grüße
emuuu

16.03.2020 - 14:46 Uhr

Der Pattern dazu nennt sich
>
.

Super danke. Das entspricht ja in etwa meinem "selber dafür sorgen, dass aufgeräumt wird".

Wäre das im Code eine korrekt Umsetzung:


public aync Task DoStuff()
{
var compensationTasks = new List<Task>();

try
{

var resultFromA = await _dataService.CallServiceA();
compensationTasks.Add(CompensateServiceA());

var resultFromB = await _dataService.CallServiceB(resultFromA);
compensationTasks.Add(CompensateServiceB(resultFromB));


var resultFromC = await _dataService.CallServiceC(resultFromA, resultFromB);
compensationTasks.Add(CompensateServiceC());

}
catch (Exception)
{
Task.WaitAll(compensationTasks.ToArray());
}

}

Würde das aber nicht die Komplexität um einen nicht unerheblichen Faktor nach oben schrauben?

15.03.2020 - 08:55 Uhr

Guten Tag zusammen,

ich habe mal eine Frage wie ich in einer Microservice-Struktur mehrere aufeinanderfolgende Abläufe failsafe aufsetzen kann.

Wenn ich mir einen monolitischen Service, der mit einer Datenbank läuft vorstelle, starte ich eine Transaction und führe meine drei DB-Zugriffe aus: SELECT A, INSERT B, UPDATE C.

Wenn jetzt C aus irgend einem Grund scheitert, habe ich in B eine Entity die da nicht hingehört, weil der ganze Request gescheitert ist und der B nicht in C referenziert wurde.
Im o.g. Beispiel würde ich ein Rollback für die Transaction durchführen und das Thema ist gegessen.

Im Microservice-Ansatz sind A, B & C eigene Services mit eigenen DBs:
Gibt es hierfür einen ähnlich einfachen Ansatz wie Transactions oder bleibt mir nichts anderes als im API-Gateway, dass die Microservices aufruft selber dafür zu sorgen, dass aufgeräumt wird (z.B: catch Exception -> DELETE B -> was mache ich wenn hier auch ein Fehler auftritt weil die DB gerade nen Problem hat)?

Beste Grüße
emuuu

20.02.2020 - 11:56 Uhr

Guten Tag zusammen,

ich habe mich bisher noch wenig Erfahrung mit Echtzeit-Apps und hätte mal eine konzeptionelle Frage:
Ich habe eine WebApp die ihre Daten aus einer API bezieht.

Nun möchte ich für längere Tasks (Generierung von Berichten, Datenanalyse blablub) gerne eine Echtzeit-Fähigkeit implementieren, die dem User im Browser eine Push-Message anzeigt "Task XY finished, documents rdy".

Meinem Verständnis nach ist SignalR für die Kommunikation zwischen dem Service der WebApp und dem Browser des Users gedacht.
Nun ist die Frage: Woher weiß die WebApp, dass der Task in der API abgeschlossen ist? Kann ich hierfür einfach in der API ebenfalls einen SignalR-Hub aufsetzen in der die WebApp sich anmeldet?

Oder soll ich dem Browser sagen, dass er direkt die API als Hub benutzen soll? (klingt für mich nach einem konzeptbruch).

Beste Grüße
emuuu

15.01.2020 - 12:14 Uhr

Perfekt danke!

Falls jemand mal über die Frage stolpert, das wäre die Lösung für meinen Anwendungsfall:


var sample = items.SelectMany(x=> Enumerable.Range(1, x.Quantity).Select(y=>x.Value));

15.01.2020 - 11:48 Uhr

Guten Tag zusammen,

ich hab gerade eine recht simple Frage, zu der ich aber keine Lösung finde.

Ich habe folgendes Objekt:


{
  "Items": [
    {
      "quantity": 200,
      "value": 24.5
    },
    ...
  ]
}

Sprich ich habe eine Menge an Items die eine Quantity und einen Value besitzen. Um das Ganze statistisch auszuwerten möchte ich nun ein Sample bestehend aus jedem einzelnen Value erstellen.
Oben gezeigtes Item würde dem Sample also 200x den Value 24.5 beisteuern.

Wie das mit Schleifen o.ä. ablaufen würde ist mir klar. Meine Frage ist: Gibt es eine Möglichkeit innerhalb einer Codezeile aus dem IEnumerable<Item> das beschriebene IEnumerable<double> zu machen?

Beste Grüße
emuuu

08.01.2020 - 09:16 Uhr

Erstmal danke für den Hinweis, sowas in die Richtung habe ich schon vermutet, allerdings nicht, dass eine fehlende Bridge das Problem sein könnte.

Zur Config finde ich nur eine local-kv.db, was eine BoltDB ist, die erstmal abenteuerlich zu öffnen war.
Problem ist, dass das die inhaltlich relativ kryptisch sind (ein paar Einträge sind klar die Endpoints der einzelnen Container) und das wild mit IDs gearbeitet wird, die ich erstmal nicht reproduzieren kann.

Also einfach eine Config copypasten mit anderem NetworkInterface wird wohl nicht klappen.

Zudem schein ich der einzige Mensch zu sein, der DockerEE auf nem WindowsServer verwendet -> wenig Beiträge zum Thema.

Ich gebe mal ein Update wenn ich was zielführendes gefunden habe.

07.01.2020 - 12:04 Uhr

Guten Tag zusammen,

ich habe jetzt schon seit längerem ein etwas abstruses Problem, bei dem ich gerade keine weitere Idee habe was ein Lösungsansatz sein könnte.

Zur Ausgangssituation:

  • ich habe eine Reverse-Proxy (Traefik) in einem Docker-Container

  • die Ports 80 und 443 sind vom Host auf den Container gemapped

  • der Host befindet sich in zwei Netzwerken Extern und Intern

  • im Netzwerk Extern ist befindet sich ein Router der die Ports 80 und 443 weiterleitet.

  • im Netzwerk Intern löst ein DNS die Domain mit der internen IP auf, sprich der Traffic aus dem Netzwerk Intern bleibt immer dort

Auf dem Host gibt es folgende Firewall-Regel:

  • Lokalerport: 80, 443
  • Remoteport: Any
  • Lokale-IP-Adresse: Any
  • Remote-IP-Adresse: Any
  • Edgeausnahmen: "Edgeausnahmen zulassen"

Nun zum Problem:

  • die Abfragen aus dem Netzwerk Intern funktionieren problemlos
  • die Abfragen aus dem Netzwerk Extern werden geblockt

Ich habe nun testweise den Container direkt ins Netzwerk Extern gebracht und die Portweiterleitung des Routers auf die IP des Containers umgestellt -> funktioniert (und ist mein aktueller workaround)
Die Router-Konfiguration kann also eigentlich nicht das Problem sein

Es scheint also der Container-Host die Anfragen zu blockieren, allerdings nur aus dem Netzwerk.
Meinem Verständnis nach ist genau dafür Option "Edgeausnahme" in der Firewall-Regel.

Ich habe die Firewall auch testweise komplett deaktiviert -> kein Erfolg

Zur Sicherheit habe ich auch geprüft, ob irgendein anderer Prozess die beiden Ports verwendet und dadurch Probleme verursacht -> Nö

Wie gesagt ich bin momentan an einem Punkt an dem ich keine Idee mehr habe, wo der Fehler noch sein kann und bin für jeden Ratschlag offen..

Beste Grüße
emuuu

27.11.2019 - 08:54 Uhr

wäre da REST auch die beste / zukunftssicherste Lösung?

Ja (Disclaimer: Meine Meinung, gibt bestimmt welche die das anders sehen)

Allerdings wirfst du hier Äpfel und Birnen zusammen
REST
HTTP POST
SOAP

REST ist ein Paradigma, dass besagt wie du deine Struktur aufbaust, so wie SOAP

POST ist eine der Request-Arten die via HTTP möglich sind (GET, POST, PUT, DELETE - um nur die wichtigsten zu nennen, siehe hierzu auch CRUD).

Die Frage ob REST oder HTTP macht also eigentlich keinen Sinn.

Beste Grüße
emuuu

26.11.2019 - 19:02 Uhr

Ich hab ZXing schon länger nicht mehr benutzt (und für UWP noch nie), aber solche Probleme hingen bei meinen iOS/Android-Projekten fast immer mit Rechten zusammen. Sprich aus irgend einem Grund möchte das Smartphone gerade nicht, dass du auf die Kamera zugreifen kannst.

So wie ich dein Problem lese fehlt irgend eine weitere Berechtigung im Manifest (Kamera wechseln o.ä. wie gesagt, ich weiß nicht welche Rechte bei UWP speziell festgelegt werden können).

Ich erinnere mich dunkel daran, dass es bei ZXing mal ein Problem mit dem Flashlight gab. Also Fehler auftraten, wenn du keine Rechte zum Nutzen des Flashlights angefordert hast (obwohl es nicht verwendet wird). Ist aber schon 2-3 Jahre her, dass ich damit zu tun hatte.

Beste Grüße
emuuu

26.11.2019 - 11:08 Uhr

Guten Tagen zusammen,

ich habe mal ein Anwenderproblem: iOS bietet seit v12 die Möglichkeit, dass per SMS versandte 2FA-Codes automatisch erkannt und als AutoFill-Option angeboten werden.

Mein Problem ist, dass die Funktion nun "weg" ist. Da ich noch recht wenige 2FA-Accounts die via SMS funktionieren habe, kann ich leider nicht genau bestimmen seit wann. Bin im Oktober auf ein iPhone 11 Pro umgestiegen - eventuell seit dem Zeitpunkt. Wurde die Funktion mit iOS 13 entfernt oder per default deaktiviert?

Kann zu dem Thema nix brauchbares finden, da die meisten Sucheinträge sich generell um 2FA oder das eben neue Feature in iOS 12 drehen.

Hatte eventuell wer schon mal das oder ein ähnliches Problem?

Beste Grüße
emuuu

P.s. Bitte keine Diskussion über die Unsicherheit von 2FA via SMS starten - Ich bin in dem Fall nur Anwender und hab keinen Einfluss auf das 2FA-Verfahren. Und 2FA via SMS ist mir lieber als gar kein 2FA.