asp.net core uses DI to implement a customized user system

大家讲道理
Release: 2017-05-28 11:41:33
Original
1922 people have browsed it

Preface

In many cases we don’t actually need the complex user system that asp.net core comes with, based on roles, various concepts, and You have to use EF Core, and in web applications, information is stored in cookie for communication (I don’t like to put it in cookies, because once I ran the web application in the safari browser on the mac system , when cross-domain cookies cannot be set, I have to use a very special method, remember it is iframe, which is quite troublesome, so I still like to put it in the custom header ), I feel kidnapped by Microsoft after using it. However, this is completely a personal preference. You can do whatever you like. I have provided another way here so that you can have one more choice.

I use asp.net core's Dependency Injection to define a set of user authentication and authorization for my own system. You can refer to this to define your own. Limited to user system.

Aspect-orientedProgramming(AOP)

In my opinion, Middleware and Filter are both aspects in asp.net core. We can put authentication and authorization in these two places. I personally prefer to put the authentication in Middleware, which can intercept and return illegal attacks early.

Dependency Injection (DI)

There are three types of dependency injectionLife cycle

1. From the initiation to the end of the same request. (services.AddScoped)

2. Each time it is injected, it is newly created. (services.AddTransient)

3. Singleton, from the beginning of the application to the end of the application. (services.AddSingleton)

My custom user class uses services.AddScoped.

Specific methods

1. Define user class


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

2. Register user class

in Startup.cs The ConfigureServices function:


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         }
Copy after login

custom user class is registered through services.AddScoped because I want it to be in the same request , Middleware, filter, controllerreference refers to the same object.

3. Inject into 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     }
Copy after login

I found that if I want to inject the interface/class into Middleware in Scoped mode, just The class/interface to be injected needs to be placed in the parameters of the Invoke function, not the constructor# of Middleware ##, I guess this is why Middleware does not inherit the base class or interface, and defines Invoke in the base class or interface. If it defines Invoke in the base class or interface, this Invoke will inevitably The parameters must be fixed, so dependency injection is difficult.

4. Only by configuring certain paths will the Middleware be used.


 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         }
Copy after login
No authentication is required for obtaining tokens and viewing api documents.

5. Inject into Filter


 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     }
Copy after login
Here I created a class with

string parameters, because considering this Filter It may be reused, such as restricting a certain interface to only be accessed by a certain user. This string can store the identification of a certain user.

Filter can also inject database access classes, so that we can obtain the corresponding user information through token in the database.

6. Using Filter


1 [TypeFilter(typeof(NeedAuthAttribute), Arguments = new object[]{ "bbb" }, Order = 1)]2 public class ValuesController : Controller
Copy after login
TypeFilter is used here to load the Filter using dependency injection, and you can set parameters and the order of the Filter.

The default Filter order is Global Settings->Controller->Action, and Order is 0 by default. We can change this order by setting Order.

7. Inject into the Controller


 1     public class ValuesController : Controller 2     { 3         private MyUser _user; 4  5         public ValuesController(MyUser user) 6         { 7             _user = user; 8         } 9         ...10     }
Copy after login
Inject into the constructor of the Controller, so that we can use our customized user in the Action of the Controller , you can know which user is currently calling this Action.

The above is the detailed content of asp.net core uses DI to implement a customized user system. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
di
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template