Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2629 connectés 

 


 Mot :   Pseudo :  
  Aller à la page :
 
 Page :   1  2  3  4  5  ..  66  67  68  ..  75  76  77  78  79  80
Auteur Sujet :

[Topic unique] .Net @ Prog

n°2360995
Yor_le_Bou​rrin
Posté le 31-08-2020 à 15:39:15  profilanswer
 

Reprise du message précédent :
Ca commence à être tendu donc. Dernière hypothèse TEntity.id est bien un string aussi dans ce cas ? Dans le cas contraire, possible que le cast ne soit pas géré. Genre string[].Contains(string) se traduit, string[].Contains(object) non

mood
Publicité
Posté le 31-08-2020 à 15:39:15  profilanswer
 

n°2360996
Implosion ​du Sord
Fesseur de chameaux
Posté le 31-08-2020 à 16:05:43  profilanswer
 

J'y ai pensé mais le champs Id de mon entité est bien un string quand j'observe les objets

 

Pour le moment j'ai contourné le problème en faisant ça :

Code :
  1. var r = await _dbSet.ToListAsync();
  2. List<TEntity> objects = r.Where(a => ids.Contains(a.Id)).ToList();
  3. return objects;


Je récupère tous mes objets qui sont en base, puis filtre dans mon backend
En temps normal, si je voie quelqu'un faire ça je le lapide...   [:antp]
Heureusement que le jeu de données n'est pas ouf en taille même dans le cas le plus défavorable (car on est bien dans un code ultra générique ici, un "BaseRepository" )

 


(en tous cas merci Taiche et Yor_le_Bourrin pour votre aide)


Message édité par Implosion du Sord le 31-08-2020 à 16:15:57

---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
n°2361121
TotalRecal​l
Posté le 02-09-2020 à 08:07:09  profilanswer
 

Pour le 2e souci tu peux confirmer que :

Code :
  1. public virtual async Task<IDictionary<TPrimaryKey, TEntity>> GetByIdAsync(IEnumerable<TPrimaryKey> ids)
  2.     {
  3.       var bidules = ids.Take(10).ToList<string>();
  4.       var objects = await _dbContext.Set<TEntity>().Where(r => bidules.Contains(r.id)).ToListAsync()
  5.       return objects.ToDictionary(x => x.Id);
  6.     }


Plante exactement pareil ?
Juste pour être sûr que l'IEnumerable ids est évalué avant la conversion LINQ to SQL, et avec un nombre d'élément et un type acceptables.


Message édité par TotalRecall le 02-09-2020 à 08:12:18

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2361146
Implosion ​du Sord
Fesseur de chameaux
Posté le 02-09-2020 à 10:10:45  profilanswer
 

Le soucis reste identique.
En général je n'ai qu'un seul élément dans ma liste, donc le volume n'est pas un soucis  [:tinostar]  
 
Notons que je ne peux pas tester strictement ce que tu demandes car TPrimaryKey n'est pas forcément un string (il y a des cas où c'est un entier, d'autres des Guid) et donc .ToList<string> refuse de compiler.
J'ai donc fait un truc comme ça :
 

Code :
  1. public virtual async Task<IDictionary<TPrimaryKey, TEntity>> GetByIdAsync(IEnumerable<TPrimaryKey> ids)
  2.         {
  3.           var bidules = (ids.Take(10) as IEnumerable<string> ).ToList<string>();
  4.           var objects = await _dbContext.Set<TEntity>().Where(r => bidules.Contains(r.id as string)).ToListAsync()
  5.           return objects.ToDictionary(x => x.Id);
  6.         }


 
J'avais testé en injectant une List<string> statique aussi. Même soucis
 
Vu que pour le moment j'ai une solution de contournement et que le jeu de données est petit, je vais attendre le retour d'un gars dans l'équipe et lui refiler le truc.
J'aime pas EF :o


---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
n°2361149
ixemul
Nan mais sans blague ! ⚡
Posté le 02-09-2020 à 10:15:24  profilanswer
 

C'est quand je vois des trucs comme ça que je suis bien content de faire du SQL à la main et du mapping avec Dapper :D


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2361156
Implosion ​du Sord
Fesseur de chameaux
Posté le 02-09-2020 à 10:45:42  profilanswer
 

ixemul a écrit :

C'est quand je vois des trucs comme ça que je suis bien content de faire du SQL à la main et du mapping avec Dapper :D


+1000
Mais je ne peux pas nier que sur de petites applications, les ORM comme EF ou NH peuvent grandement accélérer le travail (tant que l'on tombe pas sur un truc chelou comme mon cas...)


---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
n°2361157
Yor_le_Bou​rrin
Posté le 02-09-2020 à 10:47:59  profilanswer
 

Houla si même à ce niveau ça plante, ça va être tendu. Je ne vois plus que :
- Ticket MS
- Sinon surcharger le générateur de requête pour qu'il prenne en charge ton Contains : https://docs.microsoft.com/en-us/ef [...] operations
 
J'avais déjà fait ça en EF6 pour intégrer des commandes FULL TEXT, mais ils ont enfin ajouté les DbCommandInterceptor en EF Core 3

n°2361242
BilupBaloo
Posté le 03-09-2020 à 10:23:26  profilanswer
 

Comme ça, moi je ne vois qu'un pb de cast que EF n'arrive pas à faire.
 
Ça plante sur tous les types ? Pour toutes les requêtes ?

n°2361248
Yor_le_Bou​rrin
Posté le 03-09-2020 à 11:27:50  profilanswer
 

Avec la dernière version ça n'est plus ambigu :
var bidules = (ids.Take(10) as IEnumerable<string> ).ToList<string>();
var objects = await _dbContext.Set<TEntity>().Where(r => bidules.Contains(r.id as string)).ToListAsync()
 
Là le constructeur de requête n'a plus d'excuse pour confondre la méthode...

n°2361251
BilupBaloo
Posté le 03-09-2020 à 12:06:23  profilanswer
 

ça n'est plus ambigu pour la liste mais le cast du champ est peut-être en cause (r.id as string) ?
 
Est-ce que cela fonctionne en spécifiant explicitement une TEntity ?

mood
Publicité
Posté le 03-09-2020 à 12:06:23  profilanswer
 

n°2361265
Implosion ​du Sord
Fesseur de chameaux
Posté le 03-09-2020 à 13:50:16  profilanswer
 

BilupBaloo a écrit :

ça n'est plus ambigu pour la liste mais le cast du champ est peut-être en cause (r.id as string) ?
 
Est-ce que cela fonctionne en spécifiant explicitement une TEntity ?


 
En remplaçant (r.id as string) par  (r.id.ToString()) le problème reste le même.
Le soucis doit être autour de ce cast pourtant... mais bon pour le moment je vais laisser mon évaluation client-side et attendre le retour d'un gars qui maitrise bien EF pour reprendre le sujet


---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
n°2361277
Yor_le_Bou​rrin
Posté le 03-09-2020 à 14:15:14  profilanswer
 

Pas sûr que ToString soit supporté en EF Core, ni même le cast en fait. J'aurais tendance à faire "var idString = r.id as string;" avant, pour être sûr des types en effet.
 
C'est un peu pénible cette migration EF Core, pas mal d'acquis d'EF6 ont été perdus apparemment.

n°2361393
Implosion ​du Sord
Fesseur de chameaux
Posté le 04-09-2020 à 11:45:13  profilanswer
 

Yor_le_Bourrin a écrit :

Pas sûr que ToString soit supporté en EF Core, ni même le cast en fait. J'aurais tendance à faire "var idString = r.id as string;" avant, pour être sûr des types en effet.


ça n'apportera rien je pense puisque r.id est évalué côté serveur :/
mais je trouve ouf qu'un cast ne soit pas traduit... on bosse sur du SQL Server quand même derrière, c'est pas non plus exotique :o
 

Yor_le_Bourrin a écrit :

C'est un peu pénible cette migration EF Core, pas mal d'acquis d'EF6 ont été perdus apparemment.


vive Dapper !


---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
n°2369509
TotalRecal​l
Posté le 27-11-2020 à 09:48:37  profilanswer
 

Ben dis donc c'est calme :sleep:
Tout le monde fait du .Net 5 à fond et n'a plus le temps de poster ?  [:djmb]


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2369510
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2020 à 10:00:54  profilanswer
 

TotalRecall a écrit :

Ben dis donc c'est calme :sleep:
Tout le monde fait du .Net 5 à fond et n'a plus le temps de poster ?  [:djmb]


 
Nop... Core 3.1 encore ici :D


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369553
Yor_le_Bou​rrin
Posté le 27-11-2020 à 15:15:08  profilanswer
 

TotalRecall a écrit :

Ben dis donc c'est calme :sleep:
Tout le monde fait du .Net 5 à fond et n'a plus le temps de poster ?  [:djmb]


.Net 5 n'est pas LTS, donc je reste aussi en 3.1. Surtout que les modifs ne semblaient pas si énormes. On verra l'an prochain quand il y aura la 6 (LTS).
 
Sinon je suis passé à Dapper pour un projet avec une base à gros besoin de perfs / requêtes ultra optimisées : je confirme que ça dépote. Apprentissage rapide et sans accroche, à part un léger sur le mapping des one to many. Merci au topic pour le feedback :jap:

n°2369554
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2020 à 15:23:11  profilanswer
 

D'ailleurs, petite question Claims, Roles et authentification pour une WEP API .net core 3.1:
 
J'ai une appli ou j'ai des users, avec différents rôles, pouvant appartenir à différentes entités, il existe des trucs pour gérer ça ?
 
Exemple,  
 
User1:  User sur société A et Admin société B (les sociétés sont stockées en base et peuvent évoluer)
User2 : User sur société A et User sur société B
User3: Admin sur société A et Société B
User4 : User sur société A
User5: Super admin (Admin sur toutes les sociétés).
 
Le but étant de sécuriser une Web API (actuellement, un JWT Bearer uniquement pour les roles), il y a moyen d'ajouter la notion de "Societé" ?
 


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369561
Yor_le_Bou​rrin
Posté le 27-11-2020 à 16:17:51  profilanswer
 

Les policies et roles sont statiques (c'est des annotations quoi), donc tu ne pourras pas passer pas par ça pour gérer des variables (ie. les sociétés). Sauf bien sûr si tu as une API avec des routes par société, mais c'est donc du statique.
 
Ca te laisse la possibilité de renvoyer des 401 si mauvaise société dans tes méthodes.
 
Eventuellement tu pourrais faire un IAuthorizationFilter, mais faut que les paramètres de ton API soient suffisamment normalisés pour que tu puisses récupérer l'ID de ta société et le comparer à un Claim dédié dans ton token JWT

n°2369567
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2020 à 16:45:49  profilanswer
 

C'est un peu le but de ma question,
 
Aujorud'hui, j'ai un token qui ressemble à ça :
 

Code :
  1. {
  2.   "sub": "User1",
  3.   "email": "User1",
  4.   "DateCreated": "2020-11-26",
  5.   "jti": "8722208c-c3e1-42a1-891e-cb44a5c5f6b5",
  6.   "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
  7.     "Admin",
  8.     "User"
  9.   ],
  10.   "exp": 1606410960,
  11.   "iss": "Test.com",
  12.   "aud": "Test.com"
  13. }


 
Et je voudrais mapper des ID devant chaque rôles du style :

Code :
  1. {
  2.   "sub": "User1",
  3.   "email": "User1",
  4.   "DateCreated": "2020-11-26",
  5.   "jti": "8722208c-c3e1-42a1-891e-cb44a5c5f6b5",
  6.   "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
  7.     "Admin:SocA",
  8.     "User:SocB,SocC"
  9.   ],
  10.   "exp": 1606410960,
  11.   "iss": "Test.com",
  12.   "aud": "Test.com"
  13. }


 
pour récupérer à la validation du token les droits du user pour chaque société.
 
En l'écrivant, je viens de me rendre compte que je pouvais peut-être faire ça dans les Events du JwtBearer :
 

Code :
  1. options.Events = new JwtBearerEvents()
  2.                 {                 
  3.                     OnChallenge = c => { /* code pour splitter les rôles par société sur la request */}
  4.                 }


 
Après.. est-ce que c'est propre...  [:urd]  
 
 


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369569
Yor_le_Bou​rrin
Posté le 27-11-2020 à 16:59:42  profilanswer
 

OK, je n'avais pas compris que ta question portait sur le token en lui-même. Pourquoi ne pas créer des claim JWT supplémentaire ?

Code :
  1. {
  2.   "sub": "User1",
  3.   "email": "User1",
  4.   "DateCreated": "2020-11-26",
  5.   "jti": "8722208c-c3e1-42a1-891e-cb44a5c5f6b5",
  6.   "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
  7.     "Admin:SocA"
  8.   ],
  9.   "Societes": [
  10.     "SocB",
  11.     "SocC"
  12.   ]
  13.   "exp": 1606410960,
  14.   "iss": "Test.com",
  15.   "aud": "Test.com"
  16. }


Par la suite tu peux facilement te faire une policy ASP qui vérifiera tout ça. Par contre encore une fois ça m'étonnerait que tu puisses exploiter ça facilement, à moins d'avoir des controllers dédiés aux sociétés (genre /api/socA/product). Il te faudra passer par une des solutions que je donnais en dessus.
 
Edit mal compris la question, pas vu que tu avais des rôles par société. Avec ton premier json :

Code :
  1. {
  2.   "sub": "User1",
  3.   "email": "User1",
  4.   "DateCreated": "2020-11-26",
  5.   "jti": "8722208c-c3e1-42a1-891e-cb44a5c5f6b5",
  6.   "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
  7.     "Admin:SocA",
  8.     "User:SocB,SocC"
  9.   ],
  10.   "exp": 1606410960,
  11.   "iss": "Test.com",
  12.   "aud": "Test.com"
  13. }


Tu peux tout à fait exploiter de manière plus propre ce modèle, toujours via les policies ASP. Les rôles sont de toute façon à présent déconseillés (mais pas deprecated) par MS il me semble.


Message édité par Yor_le_Bourrin le 27-11-2020 à 18:05:58
n°2369571
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2020 à 17:07:21  profilanswer
 

Mouais... c'est finalement moins pratique que ce que j'avais envisagé de prime abord donc.. à savoir garder les rôles "classique" dans le Jwt et rajouter une couche Rôle/Société dans mon objet User chargé.
 
Avec vérification de l'opération sur la société avant le reste du code et levé d'exception si non autorisée (encapsulé dans un handler d'exception global).
 
C'est toujours relous les habilitations :D


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369573
Yor_le_Bou​rrin
Posté le 27-11-2020 à 17:31:09  profilanswer
 

Clairement pour moi dans ton cas le plus pratique reste l'exception + handler. Les claims JWT ne sont là que pour t'éviter de faire un appel DB en plus.

n°2369576
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2020 à 17:36:14  profilanswer
 

Je vais rester sur ma solution alors :D
 
Sinon, tu sors ça d'où les rôles déconseillés par MS ? C'est remplacé par quoi ? ça m'intéresse, je pars sur un projet tout neuf et s'il y a un truc plus pérenne autant l'envisager tout de suite ;)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369579
Yor_le_Bou​rrin
Posté le 27-11-2020 à 18:05:29  profilanswer
 

Je pensais l'avoir lu, mais ça date de ASP.NET core 1. Je ne retrouve pas la ref sur le site, donc ça doit être faux :jap:
 
A titre perso je trouve que la nouvelle manière, les policies (https://docs.microsoft.com/en-us/as [...] etcore-5.0) sont plus adaptées au monde JWT que les rôles, vu que tu n'es plus limité à un claim (http://schemas.microsoft.com/ws/2008/06/identity/claims/role) mais que tu peux les combiner facilement.

n°2369580
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2020 à 18:09:54  profilanswer
 

Yor_le_Bourrin a écrit :

Je pensais l'avoir lu, mais ça date de ASP.NET core 1. Je ne retrouve pas la ref sur le site, donc ça doit être faux :jap:
 
A titre perso je trouve que la nouvelle manière, les policies (https://docs.microsoft.com/en-us/as [...] etcore-5.0) sont plus adaptées au monde JWT que les rôles, vu que tu n'es plus limité à un claim (http://schemas.microsoft.com/ws/2008/06/identity/claims/role) mais que tu peux les combiner facilement.


 
Oui, j'ai déjà joué avec les policies sur d'autres projets, mais là, pas d'utilité directe (hors la problématique soulevée plus haut, mais qui ne m'avance pas plus :D)
 
Au pire, je peux toujours en rajouter "une couche" au besoin ;)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369705
overclocke​d
Posté le 30-11-2020 à 00:36:08  profilanswer
 

ixemul a écrit :


 
Oui, j'ai déjà joué avec les policies sur d'autres projets, mais là, pas d'utilité directe (hors la problématique soulevée plus haut, mais qui ne m'avance pas plus :D)
 
Au pire, je peux toujours en rajouter "une couche" au besoin ;)


Pourquoi ne pas définir la société en tant que role ?
 
sur la doc ms https://docs.microsoft.com/en-us/as [...] etcore-5.0
If you apply multiple attributes then an accessing user must be a member of all the roles specified; the following sample requires that a user must be a member of both the PowerUser and ControlPanelUser role.
 
Edit: j'avais mal compris
peut être vaux mieux créer de new role, style adminsoca, adminsocb ...

Message cité 1 fois
Message édité par overclocked le 30-11-2020 à 00:39:01

---------------
Application 1km https://play.google.com/store/apps/ [...] ology.unkm
n°2369709
ixemul
Nan mais sans blague ! ⚡
Posté le 30-11-2020 à 09:03:00  profilanswer
 

overclocked a écrit :


Pourquoi ne pas définir la société en tant que role ?
 
sur la doc ms https://docs.microsoft.com/en-us/as [...] etcore-5.0
If you apply multiple attributes then an accessing user must be a member of all the roles specified; the following sample requires that a user must be a member of both the PowerUser and ControlPanelUser role.
 
Edit: j'avais mal compris
peut être vaux mieux créer de new role, style adminsoca, adminsocb ...


 
Ce n'est pas si simple, les "sociétés" ne sont pas figées (ce sont même des franchisés pour beaucoup, autant dire, il en arrive de nouveaux régulièrement, et certains ferment aussi).
 
De toute manière, je ne peux restreindre l'accès à une API sur le critères société, en effet, il suffit que le user soit admin d'au moins une pour pouvoir y accéder, je ne peux définir de prédicat sur la société qu'il consulte en "admin".
 
Le but est d'essayer de trouver une manière élégante de présenter les couples Rôles/Sociétés dans le JWT pour rester Stateless , mais finalement, on va se fader un state/renew token côté serveur pour vérifier les couples Rôles/Sociétés.
 


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2369931
overclocke​d
Posté le 01-12-2020 à 22:26:29  profilanswer
 

Oui je vois pas d'autres choix, toute façon tu ne peux pas compter sur  ce qu'il y a dans le token, le serveur refait pas un check ?


---------------
Application 1km https://play.google.com/store/apps/ [...] ology.unkm
n°2370401
Implosion ​du Sord
Fesseur de chameaux
Posté le 05-12-2020 à 16:10:21  profilanswer
 

TotalRecall a écrit :

Ben dis donc c'est calme :sleep:
Tout le monde fait du .Net 5 à fond et n'a plus le temps de poster ?  [:djmb]


J'ai passé une bonne partie de ma semaine à faire du portage de NuGet pour les rendre compatible .NET 5.0 !


---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
n°2372120
ixemul
Nan mais sans blague ! ⚡
Posté le 21-12-2020 à 18:52:56  profilanswer
 

J'ai ma solution pour mon problème de gestion de droits évoqués précédemment !
 
Vive les policy et l'authorization handler !!!
 
 
Commençons par le resultat :
 

Code :
  1. [HttpDelete]
  2.         [AuthRequirement("SupAdmin" )]
  3.         public async Task<Unit> Delete(DeleteGroupeCommandRequest command)
  4.         {
  5.             return await Mediator.Send(command);
  6.         }
  7.         [HttpGet]
  8.         [AuthRequirement("Admin","Grp",AuthRequirement.ResourceType.Request, "groupeId" )]
  9.         public async Task<ActionResult<GetGroupeCommandResponse>> Get([FromQuery] int groupeId )
  10.         {
  11.             var command = new GetGroupeCommandRequest() { GroupeId = groupeId };
  12.             return await Mediator.Send(command);
  13.         }


 
j'ai donc un attribut AuthRequirement qui permet de définir le role : "SupAdmin","Admin" ou "User",  puis une Entite : "Grp","Soc","Etb" et enfin la description du champs de request que je veux "proteger".
 
Pour ce faire donc, on implémente un handler complet :
 

Code :
  1. public class AuthRequirement : IAuthorizationRequirement
  2.     {
  3.         public enum ResourceType
  4.         {
  5.             None,
  6.             Request,
  7.             Body
  8.         }
  9.         public class RessourceProtect
  10.         {
  11.             public ResourceType ResourceType { get; set; }
  12.             public string Resource { get; set; }
  13.         }
  14.         public AuthRequirement(string role, string entite, RessourceProtect ressourceProtected)
  15.         {
  16.             Role = role;
  17.             Entite = entite;
  18.             RessourceProtected = ressourceProtected;
  19.         }
  20.         public string Role { get; set; }
  21.         public string Entite { get; set; }
  22.         public RessourceProtect RessourceProtected { get; set; }
  23.     }
  24. public class AuthRequirementAttribute : AuthorizeAttribute
  25.     {
  26.         const string POLICY_PREFIX = "AuthRequirement";
  27.         public AuthRequirementAttribute(string role, string entite = "All", AuthRequirement.ResourceType ressourceTypeProtect = AuthRequirement.ResourceType.None, string ressourceNameProtect = null )
  28.         {
  29.             // Policy = $"{POLICY_PREFIX}§{role}§{entite}";
  30.             var policy = JsonSerializer.Serialize(new AuthRequirement(role, entite, new AuthRequirement.RessourceProtect() { ResourceType = ressourceTypeProtect, Resource = ressourceNameProtect }));
  31.             Policy = $"{POLICY_PREFIX}§{policy}";
  32.         }
  33.     }
  34. public class AuthRequirementHandler : AuthorizationHandler<AuthRequirement>
  35.     {
  36.         public IMediator Mediator { get; private set; }
  37.         public IHttpContextAccessor HttpContextAccessor { get; private set; }
  38.         public AuthRequirementHandler(IMediator mediator, IHttpContextAccessor httpContextAccessor)
  39.         {
  40.             Mediator = mediator;
  41.             HttpContextAccessor = httpContextAccessor;
  42.         }
  43.         protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthRequirement requirement)
  44.         {
  45.             var roleClaims = context.User.Claims.Where(c => c.Type == "Roles" ).FirstOrDefault().Value;
  46.             var userroles = JsonSerializer.Deserialize<UserRoleDto[]>(roleClaims);
  47.             if (userroles.Where(c => c.Role == "SupAdmin" ).FirstOrDefault() != null)
  48.             {
  49.                 context.Succeed(requirement);
  50.             }
  51.             else
  52.             {
  53.                 var requiredRoles = userroles.Where(r => r.Role == requirement.Role && r.Entite == requirement.Entite);
  54.                 if (requirement.RessourceProtected.ResourceType == AuthRequirement.ResourceType.None && requiredRoles.FirstOrDefault() != null)
  55.                 {
  56.                     context.Succeed(requirement);
  57.                 }
  58.                 else if (requirement.RessourceProtected.ResourceType == AuthRequirement.ResourceType.Request)
  59.                 {
  60.                     var resValue = HttpContextAccessor.HttpContext.Request.Query[requirement.RessourceProtected.Resource];
  61.                     if (requiredRoles.Where(r => r.EntiteId == resValue).FirstOrDefault() != null)
  62.                     {
  63.                         context.Succeed(requirement);
  64.                     }
  65.                 }
  66.                 else if (requirement.RessourceProtected.ResourceType == AuthRequirement.ResourceType.Body)
  67.                 {
  68.                     // HttpContextAccessor.HttpContext.Request.Body.ReadAsync<object>();
  69.                     HttpContextAccessor.HttpContext.Request.EnableBuffering();
  70.                     var dataArray = HttpContextAccessor.HttpContext.Request.BodyReader.ReadAsync().Result;
  71.                     var body = Encoding.UTF8.GetString(dataArray.Buffer.ToArray());
  72.                     HttpContextAccessor.HttpContext.Request.Body.Position = 0;
  73.                    var jsonReader = JsonReaderWriterFactory.CreateJsonReader(dataArray.Buffer.ToArray(), new System.Xml.XmlDictionaryReaderQuotas());
  74.                     var root = XElement.Load(jsonReader);
  75.                     var protectedRessource = root.XPathSelectElement($"//{requirement.RessourceProtected.Resource}" ).Value;
  76.                     if (requiredRoles.Where(r => r.EntiteId == protectedRessource).FirstOrDefault() != null)
  77.                     {
  78.                         context.Succeed(requirement);
  79.                     }
  80.                 }
  81.                /* if (requiredRole != null)
  82.                 {
  83.                     context.Succeed(requirement);
  84.                 }*/
  85.             }
  86.             return Task.CompletedTask;
  87.         }
  88.     }
  89. public class AuthRequirementProvider : IAuthorizationPolicyProvider
  90.     {
  91.         const string POLICY_PREFIX = "AuthRequirement";
  92.         public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
  93.         public AuthRequirementProvider(IOptions<AuthorizationOptions> options)
  94.         {
  95.             // ASP.NET Core only uses one authorization policy provider, so if the custom implementation
  96.             // doesn't handle all policies (including default policies, etc.) it should fall back to an
  97.             // alternate provider.
  98.             //
  99.             // In this sample, a default authorization policy provider (constructed with options from the  
  100.             // dependency injection container) is used if this custom provider isn't able to handle a given
  101.             // policy name.
  102.             //
  103.             // If a custom policy provider is able to handle all expected policy names then, of course, this
  104.             // fallback pattern is unnecessary.
  105.             FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
  106.         }
  107.         public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
  108.         public Task<AuthorizationPolicy> GetFallbackPolicyAsync() => FallbackPolicyProvider.GetFallbackPolicyAsync();
  109.         // Policies are looked up by string name, so expect 'parameters' (like age)
  110.         // to be embedded in the policy names. This is abstracted away from developers
  111.         // by the more strongly-typed attributes derived from AuthorizeAttribute
  112.         // (like [MinimumAgeAuthorize()] in this sample)
  113.         public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
  114.         {
  115.             if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
  116.             {
  117.                 /*var role = policyName.Split('§')[1];
  118.                 var entite = policyName.Split('§')[2];*/
  119.                 var policy = new AuthorizationPolicyBuilder();
  120.                 var policyString = policyName.Split('§')[1];
  121.                 var policyObject = JsonSerializer.Deserialize<AuthRequirement>(policyString);
  122.                 //policy.AddRequirements(new AuthRequirement(role, entite));
  123.                 policy.AddRequirements(policyObject);
  124.                 return Task.FromResult(policy.Build());
  125.             }
  126.             return Task.FromResult<AuthorizationPolicy>(null);
  127.         }
  128.     }


 
 
Bon, il y a encore un peu de code porky dedans, il faut que je gère les niveau Supadmin, admin et user avec un Enum Flag + Bitmask pour retirer des ifs, mais la mécanique est là !  
 
 :love:  
 
Ha oui... .Net core, Autofac, MediatR et Automapper, c'est vraiment de la bonne came !!!  


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2372139
DiB91
Bwaaaaaaah
Posté le 22-12-2020 à 10:01:52  profilanswer
 

Coucou les copains :)

 

Parlant de .NET Core, je me suis enfin ( :o ) lancé sur un projet de site web en ASP .NET Core MVC.
Je suis encore pas mal dérouté pour le moment, je cherche encore mes contrôleurs, mes actions... mais bon ça va rentrer je m'inquiète pas.

 

Par contre un truc me gonfle profondément : je suis obligé de relancer tout le débogage quand je modifie un pauvre texte dans une vue ? :??:
Rien que changer le "welcome" dans Index.cshtml F5 et CTRL+F5 ne changent rien. Je suis obligé de redémarrer toute l'appli pour que ce soit pris en compte, c'est pas du tout pratique pour du web (je débogue avec MS EDGE, et le débogage de script est activé).
Y a un truc que j'ai pas compris ?

 

En ASP .NET MVC 5, avec les bundles c'était assez dingue de pouvoir modifier le CSS dans VS et la modif s'appliquait en temps réel dans mon navigateur :love:

 

EDIT : Ah, et il faut penser à installer le package de prise en charge (runtime) pour ASP .NET Core MVC 5.0 sur le serveur IIS :o


Message édité par DiB91 le 22-12-2020 à 12:00:28

---------------
La DiBerie | Rehost | Link
n°2372168
Yor_le_Bou​rrin
Posté le 22-12-2020 à 15:08:21  profilanswer
 

Pas obligé d'installer le package, tu peux aussi faire du standalone. Ton appli va grossir, mais pas forcément beaucoup vu que .net 5 va rajouter seulement les dépendances réellement utilisées. C'est d'ailleurs son gros atout par rapport à 3.1 de mon point de vue.

 

@Ixemul : bien joué, c'est propre :jap:. Je vois qu'on a la même stack aussi (sauf autofac, l'IoC de base me suffit). Un petit swashbuckle pour la doc et tu as une API super clean.

Message cité 1 fois
Message édité par Yor_le_Bourrin le 22-12-2020 à 15:08:43
n°2372173
ixemul
Nan mais sans blague ! ⚡
Posté le 22-12-2020 à 16:19:50  profilanswer
 

Yor_le_Bourrin a écrit :

Pas obligé d'installer le package, tu peux aussi faire du standalone. Ton appli va grossir, mais pas forcément beaucoup vu que .net 5 va rajouter seulement les dépendances réellement utilisées. C'est d'ailleurs son gros atout par rapport à 3.1 de mon point de vue.
 
@Ixemul : bien joué, c'est propre :jap:. Je vois qu'on a la même stack aussi (sauf autofac, l'IoC de base me suffit). Un petit swashbuckle pour la doc et tu as une API super clean.


 
 :jap:  
 
Autofac c'est génial car ça rajoute de l'interceptor et des petits trucs sympas comme le propertiesAutoWired qui permette de faire une classe de base qui intercepte les injections sans avoir à se taper les constructeurs partout.
 
Je viens d'améliorer le concept en virant le ResourceType d'attribut, je récupère directement dans le context le type d'attribution de chaque paramètres sur le endpoint
 

Code :
  1. ((Endpoint)context.Resource).Metadata.GetMetadata<ControllerActionDescriptor>().Parameters[0].BindingInfo.BindingSource.DisplayName


 
ici pour le paramètre N°1 du array ça me renvoie directement Body ou Request en fonction de ma méthode de controleur.
 
 
Ha oui, je viens de virer le morceau bien porky à base de Xelement pour utiliser du JToken, c'est bien plus joli :D
 
Mes attributes deviennent donc :
 

Code :
  1. [HttpPut]
  2. [AuthRequirement("Admin", "Grp", "groupe.id" )]
  3. public async Task<Unit> Update([FromBody]UpdateGroupeCommandRequest command)
  4. {
  5.     return await Mediator.Send(command);
  6. }


 
Avec un Json pour UpdateGroupeCommandRequest  

Code :
  1. "groupe": {
  2.     "id": 25,
  3.     "raisonSociale": "Raison sociale du groupe",
  4.     "actif": true
  5.   }
  6. }


 
 
et pour un param request :
 

Code :
  1. [HttpGet]
  2. [AuthRequirement("Admin","Grp", "groupeId" )]
  3. public async Task<ActionResult<GetGroupeCommandResponse>> Get([FromQuery] int groupeId )
  4. {
  5.     var command = new GetGroupeCommandRequest() { GroupeId = groupeId };
  6.     return await Mediator.Send(command);
  7. }


 
Le tout géré avec des flag Enum

Code :
  1. [Flag]
  2. public enum Roles
  3. {
  4.     None = 0,
  5.     User = 1,
  6.     Admin = 16,
  7.     SupAdmin = 512
  8. }
  9. [Flag]
  10. public enum Entites
  11. {
  12.     None = 0,
  13.     Etb = 1,
  14.     Soc = 2,
  15.     Grp = 4
  16. }


 
(j'ai gardé de la place entre user/ admin et admin/supadmin au cas où... :o )
 
Et j'ai évidemment un Swagger pour l'API :D


Message édité par ixemul le 22-12-2020 à 16:20:30

---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2372174
ixemul
Nan mais sans blague ! ⚡
Posté le 22-12-2020 à 16:23:27  profilanswer
 

C'est ma première archi hexagonale d'ailleurs... et la vache ! on en chie un peu à la mise en oeuvre, mais ça ouvre tellement de perspective pour après  :love:


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2372185
DiB91
Bwaaaaaaah
Posté le 22-12-2020 à 17:50:09  profilanswer
 

Allez, un petit crosstopic depuis le topic de Rehost :)
 
Y en a't-il par ici qui ont déjà eu affaire à la classe JavaScript Navigator.clipboard ?
 
J'aurai besoin de récupérer la Promise que ça me return via un appel Ajax vers mon contrôleur MVC.
 
Le but, c'est d'envoyer au serveur (pour enregistrement en BDD) le contenu (image) du presse papier... J'arrive à récupérer du text (via Navigator.clipboard.readText(), qui renvoie une chaine de caractère), mais pas d'objet "Promise" (via Navigator.clipboard.read()).
J'obtiens au mieux un Object dont je ne sais pas trop quoi faire de l'autre côté...
 
Une idée ?


---------------
La DiBerie | Rehost | Link
n°2372189
ixemul
Nan mais sans blague ! ⚡
Posté le 22-12-2020 à 19:28:23  profilanswer
 

DiB91 a écrit :

Allez, un petit crosstopic depuis le topic de Rehost :)

 

Y en a't-il par ici qui ont déjà eu affaire à la classe JavaScript Navigator.clipboard ?

 

J'aurai besoin de récupérer la Promise que ça me return via un appel Ajax vers mon contrôleur MVC.

 

Le but, c'est d'envoyer au serveur (pour enregistrement en BDD) le contenu (image) du presse papier... J'arrive à récupérer du text (via Navigator.clipboard.readText(), qui renvoie une chaine de caractère), mais pas d'objet "Promise" (via Navigator.clipboard.read()).
J'obtiens au mieux un Object dont je ne sais pas trop quoi faire de l'autre côté...

 

Une idée ?


Si tu serialises cet objet, ça donne quoi ? ( binary serializer par exemple )


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2372237
DiB91
Bwaaaaaaah
Posté le 23-12-2020 à 14:07:15  profilanswer
 

J'essaie ça dès ma prochaine session :love:
Je pensais qu'un appel AJAX était forcément sérialisé dès lors que j'imposais dataType : JSON :??:
 
Merci pour l'idée en tout cas, je regarde.


---------------
La DiBerie | Rehost | Link
n°2372251
ixemul
Nan mais sans blague ! ⚡
Posté le 23-12-2020 à 14:59:19  profilanswer
 

Ou alors tu ne fais pas de read sur le blob...
 
un fiddle qui donne la démarche :
 
http://jsfiddle.net/bt7BU/225/
 
Pour le Promise, je vois pas... t'as un bout de code à montrer ?


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2372252
DiB91
Bwaaaaaaah
Posté le 23-12-2020 à 15:04:50  profilanswer
 

Ouep, je fais quelques screens dès que possible.
J'ai à peu près le même algo que sur le fiddle, mais je ne sais pas comment renvoyer le blob côté serveur pour lancer l'upload / la sauvegarde en base


---------------
La DiBerie | Rehost | Link
n°2372254
ixemul
Nan mais sans blague ! ⚡
Posté le 23-12-2020 à 15:11:30  profilanswer
 

DiB91 a écrit :

Ouep, je fais quelques screens dès que possible.
J'ai à peu près le même algo que sur le fiddle, mais je ne sais pas comment renvoyer le blob côté serveur pour lancer l'upload / la sauvegarde en base


 
C'est pas le blob qu'il faut renvoyer, mais le target.result (URL... mais c'est une image encodée Base 64) du reader !
 
Côté serveur, tu prends en String (rien de graveleux hein ! :o)

Message cité 1 fois
Message édité par ixemul le 23-12-2020 à 15:12:12

---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°2372255
Implosion ​du Sord
Fesseur de chameaux
Posté le 23-12-2020 à 15:26:48  profilanswer
 

ixemul a écrit :

J'ai ma solution pour mon problème de gestion de droits évoqués précédemment !
 
Vive les policy et l'authorization handler !!!
 
...
 
Ha oui... .Net core, Autofac, MediatR et Automapper, c'est vraiment de la bonne came !!!  


Je travaille en ce moment sur un composant d’autorisation, je vais regarder attentivement ce que tu as fait, ça me donnera peut-être des idées :)


---------------
[VDS]AIO Fractal Design Celsius S36 | Carte Wifi N Intel 5100 mPCIe | divers accessoire boitier Fractal Design | Away from keyboard, close to your breast
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3  4  5  ..  66  67  68  ..  75  76  77  78  79  80

Aller à :
Ajouter une réponse
 

Sujets relatifs
service web REST en VB.NET HeySpreadRequete Access avec paramètres, éxécutée en VB .Net
impersonalisation sous ASP.NET[Topic Unique] les blagues pourries de harko et florentg
Generation d'un GIF en ASP.NETAppeler un service web .NET sécurisé en Java
Prog Visual Basic "periodicité"[Oracle] Temps d'execution de requete tres long par rapport au .NET
[VB.NET] Lister des imprimantes réseauxFusion de résultats de requêtes dans une unique Table
Plus de sujets relatifs à : [Topic unique] .Net @ Prog


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR