Maison  >  Article  >  développement back-end  >  asp.net core utilise DI pour implémenter un système utilisateur personnalisé

asp.net core utilise DI pour implémenter un système utilisateur personnalisé

大家讲道理
大家讲道理original
2017-05-28 11:41:331863parcourir

Avant-propos

En fait, souvent, nous n'avons pas besoin du système utilisateur complexe fourni avec asp.net core, qui est basé sur des rôles, divers concepts, et vous devez utiliser EF Core, et dans les applications Web, les informations sont stockées dans des cookies pour la communication (je n'aime pas les mettre dans les cookies, car une fois que j'ai exécuté l'application Web dans le Navigateur Safari sur le système Mac Lorsque les cookies inter-domaines ne peuvent pas être définis, je dois utiliser une méthode très spéciale. N'oubliez pas qu'il s'agit de iframe, ce qui est assez gênant, donc j'aime toujours le mettre dans la personnalisation. headeuh), je me sens kidnappé par Microsoft après l'avoir utilisé. Mais c'est une préférence totalement personnelle. Vous pouvez faire ce que vous voulez. J'ai proposé ici une autre méthode afin que vous puissiez avoir un choix supplémentaire.

J'utilise Dependency Injection d'asp.net core pour définir un ensemble d'authentification et d'autorisation utilisateur pour mon propre système. Vous pouvez vous y référer pour définir votre propre système limité.

Programmationorientée vers l'aspect(AOP)

À mon avis, Middleware et Filter sont tous deux des aspects du noyau asp.net We. peut mettre l'authentification et l'autorisation à ces deux endroits. Personnellement, je préfère mettre l'authentification dans le Middleware, qui peut intercepter et renvoyer les attaques illégales plus tôt.

Injection de dépendance (DI)

Il existe trois types d'injection de dépendance Cycle de vie

De l'initiation à la fin d'une même requête. . (services.AddScoped)

2. Chaque fois qu'il est injecté, il est nouvellement créé. (services.AddTransient)

3. Singleton, du début de l'application à la fin de l'application. (services.AddSingleton)

Ma classe d'utilisateurs personnalisée utilise services.AddScoped.

Méthodes spécifiques

1. Définir la classe d'utilisateurs


1     // 用户类,随便写的2     public class MyUser3     {4         public string Token { get; set; }5         public string UserName { get; set; }6     }

2. Enregistrez la classe d'utilisateurs

Démarrage. La fonction ConfigureServices dans cs:


1         // This method gets called by the runtime. Use this method to add services to the container.2         public void ConfigureServices(IServiceCollection services)3         {4             ...5             // 注册自定义用户类6             services.AddScoped(typeof(MyUser));7             ...8         }

la classe d'utilisateurs personnalisée est enregistrée via services.AddScoped car je veux qu'elle soit dans la même requête , Middleware, filtre et contrôleur font référence à au même objet .

3. Injecter dans le middleware


 1     // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project 2     public class AuthenticationMiddleware 3     { 4         private readonly RequestDelegate _next; 5         private IOptions<HeaderConfig> _optionsAccessor; 6  7         public AuthenticationMiddleware(RequestDelegate next, IOptions<HeaderConfig> optionsAccessor) 8         { 9             _next = next;10             _optionsAccessor = optionsAccessor;11         }12 13         public async Task Invoke(HttpContext httpContext, MyUser user)14         {15             var token = httpContext.Request.Headers[_optionsAccessor.Value.AuthHeader].FirstOrDefault();16             if (!IsValidate(token))17             {18                 httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;19                 httpContext.Response.ContentType = "text/plain";20                 await httpContext.Response.WriteAsync("UnAuthentication");21             }22             else23             {24                 // 设置用户的token25                 user.Token = token;26                 await _next(httpContext);27             }28         }29 30         // 随便写的,大家可以加入些加密,解密的来判断合法性,大家自由发挥31         private bool IsValidate(string token)32         {33             return !string.IsNullOrEmpty(token);34         }35     }36 37     // Extension method used to add the middleware to the HTTP request pipeline.38     public static class AuthenticationMiddlewareExtensions39     {40         public static IApplicationBuilder UseAuthenticationMiddleware(this IApplicationBuilder builder)41         {42             return builder.UseMiddleware<AuthenticationMiddleware>();43         }44     }

J'ai découvert que si je voulais injecter l'interface/classe dans le middleware dans De manière étendue, vous devez mettre la classe/interface à injecter dans le paramètre de la fonction Invoke au lieu du du Middleware. construct Function , je suppose que c'est aussi la raison pour laquelle Middleware n'hérite pas de la classe ou de l'interface de base et ne définit pas Invoke dans la classe ou l'interface de base. S'il définit Invoke dans la classe ou l'interface de base, ce sera inévitablement Les paramètres de cet Invoke doivent être corrigés, donc l'injection de dépendances n'est pas facile.

4. Configurez certains chemins pour utiliser le Middleware


 1         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 2         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 3         { 4             loggerFactory.AddConsole(Configuration.GetSection("Logging")); 5             loggerFactory.AddDebug(); 6             // Set up nlog 7             loggerFactory.AddNLog(); 8             app.AddNLogWeb(); 9 10             // 除了特殊路径外,都需要加上认证的Middleware11             app.MapWhen(context => !context.Request.Path.StartsWithSegments("/api/token")12                                  && !context.Request.Path.StartsWithSegments("/swagger"), x =>13             {14                 // 使用自定义的Middleware15                 x.UseAuthenticationMiddleware();16                 // 使用通用的Middleware17                 ConfigCommonMiddleware(x);18             });19             // 使用通用的Middleware20             ConfigCommonMiddleware(app);21 22             // Enable middleware to serve generated Swagger as a JSON endpoint.23             app.UseSwagger();24 25             // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.26             app.UseSwaggerUI(c =>27             {28                 c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");29             });30         }31 32         // 配置通用的Middleware33         private void ConfigCommonMiddleware(IApplicationBuilder app)34         {35             // cors36             app.UseCors("AllowAll");37 38             app.UseExceptionMiddleware();39             // app.UseLogRequestMiddleware();40             app.UseMvc();41         }

Aucune authentification n'est requise pour obtenir des jetons et consulter les documents de l'API.

5. Injecter dans le filtre


 1     public class NeedAuthAttribute : ActionFilterAttribute 2     { 3         private string _name = string.Empty; 4         private MyUser _user; 5  6         public NeedAuthAttribute(MyUser user, string name = "") 7         { 8             _name = name; 9             _user = user;10         }11 12         public override void OnActionExecuting(ActionExecutingContext context)13         {14             this._user.UserName = "aaa";15         }16     }

Ici, j'ai créé une classe avec des paramètres string, car considérer ce filtre peut être réutilisée, comme restreindre une certaine interface pour qu'elle ne soit accessible qu'à un certain utilisateur. Cette chaîne peut stocker l'identification d'un certain utilisateur.

Le filtre peut également injecter des classes d'accès à la base de données, afin que nous puissions obtenir les informations utilisateur correspondantes via un jeton dans la base de données.

6. Utiliser le filtre


1 [TypeFilter(typeof(NeedAuthAttribute), Arguments = new object[]{ "bbb" }, Order = 1)]2 public class ValuesController : Controller

TypeFilter est utilisé ici pour charger le filtre qui utilise l'injection de dépendances et peut définir des paramètres, comme pour l'ordre des filtres. .

L'ordre de filtre par défaut est Paramètres globaux->Contrôleur->Action, et l'ordre est 0 par défaut. Nous pouvons modifier cet ordre en définissant l'ordre.

7. Injecter dans le contrôleur


 1     public class ValuesController : Controller 2     { 3         private MyUser _user; 4  5         public ValuesController(MyUser user) 6         { 7             _user = user; 8         } 9         ...10     }

Injecter dans le constructeur du contrôleur afin que nous puissions utiliser notre personnalisation dans l'utilisateur Action du contrôleur, vous pouvez savoir quel utilisateur appelle actuellement cette action.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn