.net core下访问控制层的实现

在上一篇[.net core下对于附件上传下载的实现]主要介绍了 .net core下文件上传下载的相关操作,本篇主要介绍下对于权限验证如何通过自定义的中间件进行拦截实现。

对于一般的程序而言,如果在未登录的情况下理应是没有对应的权限访问对应的页面的,同时,不同的用户也需要验证该用户权限是否满足条件。

对于后端服务来说,就需要有个中间层进行拦截,验证对应的http请求是否满足权限要求。

这里我们用到了Middleware-请求管道,通过自定义中间件的方式来实现对Http请求的拦截,实现相关验证。

对于Middleware-请求管道的原理和解释可以参考这篇文章:Middleware-请求管道的构成

实现逻辑

用户在登录成功后,我们在服务端会自动生成一个Token,这个Token会绑定对应的权限,同时保存到Redis中。

我们自定义的中间层会拦截请求,获取请求中的Token是否合法,若不合法会对该请求进行拦截。

通过使用UseMiddleware扩展方法,将拦截到的HttpContext进行相应的逻辑处理。

具体代码

首先我们自定义一个权限控制的中间件,SecurityMiddleware类就是我们具体的逻辑实现。

public static IApplicationBuilder UseSecurity(this IApplicationBuilder builder)
{
    return builder.UseMiddleware<SecurityMiddleware>();
}

Startup.cs中的Configure方法下,我们添加我们自定义的中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseSwagger();
    app.UseSwaggerUI(c => {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "我的API V1");
    });

    app.UseSecurity();//自定义中间件

    app.UseMvc();
}

接下来我们具体实现对应的SecurityMiddleware类,主要实现对应的Invoke方法

public async Task Invoke(HttpContext context)
{
    string path = context.Request.Path.ToString().ToLower();

    // 判断请求的路径是否是排除权限限制的(如登录页,登录页)
    if (excludeUrl.Contains(path))
    {
        await _next(context);
        return;
    }

    // 寻找header中的token
    string userToken = string.Empty;            
    bool hasValue = context.Request.Headers.TryGetValue(INVOKER_TOKEN_HEADER, out StringValues token);
    if (!hasValue || token.Count == 0)
    {
        // 若header没取到token,则尝试从cookie中获取
        userToken = context.Request.Cookies[USER_TOKEN_COOKIE_NAME];
        if(string.IsNullOrWhiteSpace(userToken))
        {
            // TODO: 尚未登录,未经授权
            await CreateUnauthorizedResponse(context);

            return;
        }
    }
    else
    {
        userToken = token[0];
    }

    //根据对应的Token到Redis中找对应的权限数据,若没找到,说明没有授权
    var userInfo = await GetUserInfo(userToken);
    if (userInfo == null)
    {
        // TODO: 尚未登录,未经授权
        await CreateUnauthorizedResponse(context);
        return;
    }

    //可继续针对请求判断是否有相对应的权限
}

对应构造Response方法:

private static async Task CreateUnauthorizedResponse(HttpContext context)
{
    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
    context.Response.ContentType = "application/json;charset=utf-8";

    ResponseResult result = new ResponseResult
    {
        Result = false,
        ErrorMessage = "您需要登录后访问此资源,请先进行登录操作。",
        Code = ResponseCode.Unauthorized
    };

    await context.Response.WriteAsync(JsonConvert.SerializeObject(result), Encoding.UTF8);
}

到这里,我们基本上实现的对应的控制访问。

总结

对于本篇来说,还是需要去了解下 .net core的运行原理,以便更好的去实现你想要的方法。

作者:玄冰
欢迎关注我的微信公众号和博客小程序
欢迎关注我的公众号 欢迎关注我的公众号