ASP.NET Core按用户等级授权的方法

验证和授权是两个独立但又存在联系的过程。验证是检查访问者的合法性,授权是校验访问者有没有权限查看资源。它们之间的联系——先验证再授权。

贯穿这两过程的是叫 Claim 的东东,可以叫它“声明”。没什么神秘的,就是由两个字符串组成的对象,一曰 type,一曰 value。type 和 value 有着映射关系,类似字典结构的 key 和 value。Claim 用来收集用户相关信息,比如

UserName = admin
Age = 105
Birth = 1990,4,12
Address = 火星街130号

ClaimTypes 静态类定义了一些标准的 type 值。如用户名Name,国家Country,手机号MobilePhone,家庭电话HomePhone 等等。你也可以自己定义一个,反正就是个字符串。

另外,还有一个ClaimValueTypes 辅助类,也是一组字符串,用于描述 value 的类型。如Integer、HexBinary、String、DnsName 等。其实所有 value 都是用字符串表示的,ValueTypes 只是基于内容本身的含义而定义的分类,在查找和分析 Claim 时有辅助作用。比如,值是 “00:15:30”,可以认为其 ValueType 是 Time,这样在分析这些数据时可以方便一些。

一般,代码会在 Sign in 前收集这些用户信息。作用是为后面的授权做准备。授权时会对这些用户信息进行综合评估,以决定该用户是否有能力访问某些资源。

回到本文主题。本文的重点是说授权,老周的想法是根据用户的等级来授权。比如,用户A的等级是2,如果某个URL要求4级以上的用户才能访问,那么A就无权访问了。

为了简单,老周就不建数据库这么复杂的东西了,直接写个类就好了。

public class User
{
    public string? UserName { get; set; }
    public string? Password { get; set; }

    /// <summary>
    /// 用户等级,1-5
    /// </summary>
    public int Level { get; set; } = 1;
}

上面类中,Level 属性表示的是用户等级。然后,用下面的代码来产生一些用户数据。

public static class UserDatas
{
    internal static readonly IEnumerable<User> UserList = new User[]
    {
        new(){UserName="admin", Password="123456", Level=5},
        new(){UserName="kitty", Password="112211", Level=3},
        new(){UserName="bob",Password="215215", Level=2},
        new(){UserName="billy", Password="886600", Level=1}
    };

    // 获取所有用户
    public static IEnumerable<User> GetUsers() => UserList;

    // 根据用户名和密码校对后返回的用户实体
    public static User? CheckUser(string username, string passwd)
    {
        return UserList.FirstOrDefault(u => u.UserName!.Equals(username, StringComparison.OrdinalIgnoreCase) && u.Password == passwd);
    }
}

这样的功能,对于咱们今天要说的内容,已经够用了。

关于验证,这里不是重点。所以老周用最简单的方案——Cookie。

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(opt =>
{
    opt.LoginPath = "/UserLog";
    opt.LogoutPath = "/Logout";
    opt.AccessDeniedPath = "/Denied";
    opt.Cookie.Name = "ck_auth_ent";
    opt.ReturnUrlParameter = "backUrl";
});

这个验证方案是结合 Session 和 Cookie 来完成的,也是Web身份验证的经典方案了。上述代码中我配置了一些选项:

LoginPath——当 SessionID 和 Cookie 验证不成功时,自动转到些路径,要求用户登录。

LogoutPath——退出登录(注销)时的路径。

AccessDeniedPath——访问被拒绝后转到的路径。

ReturnUrlParameter——回调URL,就是验证失败后会转到登录URL,然后会在URL参数中加一个回调URL。这个选项就是配置这个参数的名称的。比如这里我配置为backUrl。假如我要访问/home,但是,验证失败,跳转到 /UserLog 登录,这时候会在URL后面加上 /UserLog?backUrl=/home。如果登录成功且验证也成功了,就会跳转回 backUrl指定的路径(/home)。

这里要注意的是,我们不能把要求输入用户名和密码作为验证过程。验证由内置的CookieAuthenticationHandler 类去处理,它只验证 Session 和 Cookie 中的数据是否匹配,而不是检查用户名/密码对不对。你想想,如果把检查用户名和密码作为验证过程,那岂不是每次都要让用户去输入一次?说不定每访问一个URL都要验证一次的,那用户不累死?所以,输入用户名/密码登录只在 LoginPath 选项中配置,只在必要时输入一次,然后配合 session 和 cookie 把状态记录下来,下次再访问,只验证此状态即可,不用再输入了。

LogoutPath 和AccessDeniedPath 我就不弄太复杂了,直接这样就完事。

app.MapGet("/Denied", () => "访问被拒绝");
app.MapGet("/Logout", async (HttpContext context) =>
{
    await context.SignOutAsync();
});

对于 LoginPath,我用一个 Razor Pages 来处理。

@page
@using MyApp
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Authentication.Cookies
@using System.Security.Claims
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers

<form method="post">
    <style>
        label{
            display:inline-block;
            min-width:100px;
        }
    </style>
    <div>
        <label for="userName">用户名:</label>
        <input type="text" name="userName" />
    </div>
    <div>
        <label for="passWord">密码:</label>
        <input type="password" name="passWord" />
    </div>
    <div>
        <button type="submit">登入</button>
    </div>
</form>

@functions{
    //[IgnoreAntiforgeryToken]
    public async void OnPost(string userName, string passWord)
    {
        var u = UserDatas.CheckUser(userName, passWord);
        if(u != null)
        {
            Claim[] cs = new Claim[]
            {
                new Claim(ClaimTypes.Name, u.UserName!),
                new Claim("level", u.Level.ToString())  //注意这里,收集重要情报
            };
            ClaimsIdentity id = new(cs, CookieAuthenticationDefaults.AuthenticationScheme);
            ClaimsPrincipal p = new(id);
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, p);
            //HttpContext.Response.Redirect("/");
        }
    }
}

其他的各位可以不关注,重点是 OnPost 方法,首先用刚才写的UserDatas.CheckUser 静态方法来验证用户名和密码(这个是要我们自己写代码来完成的,CookieAuthenticationHandler 可不负责这个)。用户名和密码正确后,咱们就要收集信息了。收集啥呢?这个要根据你稍后在授权时要用到什么来决定的。就拿今天的主题来讲,我们需要知道用户等级,所以要收集 Level 属性的值。这里 ClaimType 我直接用“level”,Value 就是 Level 属性的值。

收集完用户信息后,要汇总到ClaimsPrincipal 对象中,随后调用HttpContext.SignInAsync 扩展方法,会触发CookieAuthenticationHandler 去保存状态,因为它实现了IAuthenticationSignInHandler 接口,从而带有SignInAsync 方法。

var ticket = new AuthenticationTicket(signInContext.Principal!, signInContext.Properties, signInContext.Scheme.Name);
    // 保存 Session
   if (Options.SessionStore != null)
   {
       if (_sessionKey != null)
       {
           // Renew the ticket in cases of multiple requests see: https://github.com/dotnet/aspnetcore/issues/22135
           await Options.SessionStore.RenewAsync(_sessionKey, ticket, Context, Context.RequestAborted);
       }
       else
       {
           _sessionKey = await Options.SessionStore.StoreAsync(ticket, Context, Context.RequestAborted);
       }

       var principal = new ClaimsPrincipal(
           new ClaimsIdentity(
               new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
               Options.ClaimsIssuer));
       ticket = new AuthenticationTicket(principal, null, Scheme.Name);
   }
  // 生成加密后的 Cookie 值
   var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());

    // 追加 Cookie 到响应消息中
   Options.CookieManager.AppendResponseCookie(
       Context,
       Options.Cookie.Name!,
       cookieValue,
       signInContext.CookieOptions);
 ……

----------------------------------------------------------------------------------------

好了,上面的都是周边工作,下面我们来干正事。

授权大体上分为两种模式:

1、基于角色授权。即“你是谁就给你相应的权限”。你是狼人吗?你是预言家吗?你是女巫吗?你是好人吗?是狼人就赋予你杀人的权限。

2、基于策略。老周觉得这个灵活性高一点(纯个人看法)。一个策略需要一定数量的约束条件,是否赋予用户权限就看他能否满足这些约束条件了。约束实现IAuthorizationRequirement 接口。这个接口未包含任何成员,因此你可以自由发挥了。

这只不过是按用途来划分的,若从类型本质上看,就是一堆IAuthorizationRequirement 组合起来提供给了AuthorizationHandlerContext,AuthorizationHandlerContext 再通过一堆IAuthorizationHandler 来处理。最后由IAuthorizationEvaluator 去总结授权的结果。

这里咱们需要的约束条件是用户等级,所以,咱们实现一个LevelAuthorizationRequirement。

public class LevelAuthorizationRequirement : IAuthorizationRequirement
 {
     public int Level { get; private set; }

     public LevelAuthorizationRequirement(int lv)
     {
         Level = lv;
     }
 }

授权处理有两个接口:

1、IAuthorizationHandler:处理过程,一个授权请求可以执行多个IAuthorizationHandler。一般用于授权过程中的某个阶段(或针对某个约束条件)。一个授权请求可以由多IAuthorizationHandler 参与处理。

2、IAuthorizationEvaluator:综合评估是否决定授权。评估一般在各种IAuthorizationHandler 之后进行收尾工作。所以只执行一次就可以了,用于总结整个授权过程的情况得出最终结论(放权还是不放权)。

ASP.NET Core 内置了DefaultAuthorizationEvaluator,这是默认实现,如无特殊需求,我们不会重新实现。

public class DefaultAuthorizationEvaluator : IAuthorizationEvaluator
{
    public AuthorizationResult Evaluate(AuthorizationHandlerContext context)
        => context.HasSucceeded
            ? AuthorizationResult.Success()
            : AuthorizationResult.Failed(context.HasFailed
                ? AuthorizationFailure.Failed(context.FailureReasons)
                : AuthorizationFailure.Failed(context.PendingRequirements));
}

所以,咱们的代码可以选择实现一个抽象类:AuthorizationHandler<TRequirement>,其中,TRequirement 需要实现IAuthorizationRequirement 接口。这个抽象类已经满足咱们的需求了。

public class LevelAuthorizationHandler : AuthorizationHandler<LevelAuthorizationRequirement>
{
    // 策略名称,写成常量方便使用
    public const string POLICY_NAME = "Level";

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, LevelAuthorizationRequirement requirement)
    {
        // 查找声明
        Claim? clm = context.User.Claims.FirstOrDefault(c => c.Type == "level");
        if(clm != null)
        {
            // 读出用户等级
            int lv = int.Parse(clm.Value);
            // 看看用户等级是否满足条件
            if(lv >= requirement.Level)
            {
                // 满足,标记此阶段允许授权
                context.Succeed(requirement);
            }
        }
        return Task.CompletedTask;
    }
}

在授权请求启动时,AuthorizationHandlerContext (上下文)对象会把所有IAuthorizationRequirement 对象添加到一个哈希表中(HashSet<T>),表示一大串正等着授权处理的约束条件。

当我们调用 Succeed 方法时,会把已满足要求的IAuthorizationRequirement 传递给方法参数。在 Success 方法内部会从哈希表中删除此IAuthorizationRequirement,以表示该条件已满足了,不必再证。

public virtual void Succeed(IAuthorizationRequirement requirement)
{
    _succeedCalled = true;
    _pendingRequirements.Remove(requirement);
}

记得要在服务容器中注册,否则咱们写的 Handler 是不起作用的。

builder.Services.AddSingleton<IAuthorizationHandler, LevelAuthorizationHandler>();

builder.Services.AddSingleton<IAuthorizationHandler, LevelAuthorizationHandler>();
builder.Services.AddAuthorizationBuilder().AddPolicy(LevelAuthorizationHandler.POLICY_NAME, pb =>
{
    pb.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
    pb.AddRequirements(new LevelAuthorizationRequirement(3));
});

策略的名称我们前面以常量的方式定义了,记得否?

  public const string POLICY_NAME = "Level";

AddAuthenticationSchemes 是把此授权策略与一个验证方案关联,当进行鉴权时顺便做一次验证。上述代码我们关联 Cookie 验证即可,这个在文章前面已经设置了。AddRequirements 方法添加我们自定义的约束条件,这里我设置的用户等级是 3 —— 用户等级要 >= 3 才允许访问。

下面写个 MVC 控制器来检验一下是否能正确授权。

public class HomeController : Controller
{
    [HttpGet("/")]
    [Authorize(Policy = LevelAuthorizationHandler.POLICY_NAME)]
    public IActionResult Index()
    {
        return View();
    }
}

这里咱们用基于策略的授权方式,所以[Authorize]特性要指定策略名称。

好,运行。本来是访问根目录 / 的,但由于验证不通过,自动跳到登录页了。

注意URL上的 backUrl 参数:?backUrl=/。本来要访问 / 的,所以登录后再跳回 / 。我们选一个用户等级为 5 的登录。

由于用户等级为 5,是 >=3 的存在,所以授权通过。

现在,把名为 ck_auth_ent 的Cookie删除。

这个 ck_auth_ent 是在代码中配置的,还记得吗?

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(opt =>
{
    opt.LoginPath = "/UserLog";
    opt.LogoutPath = "/Logout";
    opt.AccessDeniedPath = "/Denied";
    opt.Cookie.Name = "ck_auth_ent";
    opt.ReturnUrlParameter = "backUrl";
});

现在咱们找个用户等级低于 3 的登录。

登录后被拒绝访问。

到此为止,好像、貌似、似乎已大功告成了。但是,老周又发现问题了:如果我一个控制器内或不同控制器之间有的操作方法要让用户等级 3 以上的用户访问,有些操作方法只要等级在 2 以上的用户就可以访问。这该咋整呢?有大伙伴可以会说了,那就多弄几个策略,每个策略代表一个等级。

builder.Services.AddAuthorizationBuilder()
    .AddPolicy("Level3", pb =>
    {
        pb.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
        pb.AddRequirements(new LevelAuthorizationRequirement(3));
    })
    .AddPolicy("Level5", pb =>
    {
        pb.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
        pb.AddRequirements(new LevelAuthorizationRequirement(5));
    });

是的,这样确实是可行的。不过不够动态,要是我弄个策略从 Level1 到 Level10 呢,岂不要写十个?

官方有个用 Age 生成授权策略的示例让老周获得了灵感——是的,咱们就是要动态生成授权策略。需要用到一个接口:IAuthorizationPolicyProvider。这个接口可以根据策略名称返回授权策略,所以,咱们可以拿它做文章。

public class LevelAuthorizationPolicyProvider : IAuthorizationPolicyProvider
{
    private readonly AuthorizationOptions _options;

    public LevelAuthorizationPolicyProvider(IOptions<AuthorizationOptions> opt)
    {
        _options = opt.Value;
    }

    public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
    {
        return Task.FromResult(_options.DefaultPolicy);
    }

    public Task<AuthorizationPolicy?> GetFallbackPolicyAsync()
    {
        return Task.FromResult(_options.FallbackPolicy);
    }

    public Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
    {
        if(policyName.StartsWith(LevelAuthorizationHandler.POLICY_NAME,StringComparison.OrdinalIgnoreCase))
        {
            // 比如,策略名 Level4,得到等级4
            // 提取名称最后的数字
            int prefixLen = LevelAuthorizationHandler.POLICY_NAME.Length;
            if(int.TryParse(policyName.Substring(prefixLen), out int level))
            {
                // 动态生成策略
                AuthorizationPolicyBuilder plcyBd = new AuthorizationPolicyBuilder();
                plcyBd.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
                plcyBd.AddRequirements(new LevelAuthorizationRequirement(level));
                // Build 方法生成策略
                return Task.FromResult(plcyBd.Build())!;
            }
        }
        // 未处理,交由选项类去返回默认的策略
        return Task.FromResult(_options.GetPolicy(policyName));
    }
}

这样可以根据给定的策略名称,生成与用户等级相关的配置。例如,名称“Level3”,就是等级3;“Level5”就是等级5。

于是,在配置服务容器时,我们不再需要AddAuthorizationBuilder 一大段代码了,直接把LevelAuthorizationPolicyProvider 注册一下就行了。

builder.Services.AddSingleton<IAuthorizationHandler, LevelAuthorizationHandler>();
builder.Services.AddTransient<IAuthorizationPolicyProvider, LevelAuthorizationPolicyProvider>();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(opt =>
……

然后,在MVC控制器上咱们就可以666地玩了。

public class HomeController : Controller
 {
     [HttpGet("/")]
     [Authorize(Policy = $"{LevelAuthorizationHandler.POLICY_NAME}3")]
     public IActionResult Index()
     {
         return View();
     }

     [HttpGet("/music")]
     [Authorize(Policy = $"{LevelAuthorizationHandler.POLICY_NAME}2")]
     public IActionResult Foo()
         => Content("2星级用户扰民音乐俱乐部");

     [HttpGet("/movie")]
     [Authorize(Policy = $"{LevelAuthorizationHandler.POLICY_NAME}5")]
     public IActionResult Movies()
         => Content("5星级鬼畜影院");
 }

这样一来,配置不同等级的授权就方便多了。

到此这篇关于ASP.NET Core按用户等级授权的文章就介绍到这了,更多相关ASP.NET Core授权内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

赞 (0)

相关推荐

  • ASP.NET Core中的策略授权和ABP授权

    目录 ASP.NETCore中的策略授权 策略 定义一个Controller 设定权限 定义策略 存储用户信息 标记访问权限 认证:Token凭据 颁发登录凭据 自定义授权 IAuthorizationService ABP授权 创建ABP应用 定义权限 ASP.NET Core 中的策略授权 首先我们来创建一个 WebAPI 应用. 然后引入 Microsoft.AspNetCore.Authentication.JwtBearer 包. 策略 Startup 类的 ConfigureServ

  • 浅谈ASP.NET Core 中jwt授权认证的流程原理

    1,快速实现授权验证 什么是 JWT ?为什么要用 JWT ?JWT 的组成? 这些百度可以直接找到,这里不再赘述. 实际上,只需要知道 JWT 认证模式是使用一段 Token 作为认证依据的手段. 我们看一下 Postman 设置 Token 的位置. 那么,如何使用 C# 的 HttpClient 访问一个 JWT 认证的 WebAPI 呢? 下面来创建一个 ASP.NET Core 项目,尝试添加 JWT 验证功能. 1.1 添加 JWT 服务配置 在 Startup.cs 的 Confi

  • ASP.NET Core 6.0 添加 JWT 认证和授权功能

    目录 序言 相关名词 认证(Authentication) 基本步骤 1 安装 Nuget 包 2 准备配置信息 3 添加服务 4 调用中间件 5 JwtHelper 类实现 6 控制器配置 7 测试调用 授权(Authorization) 相关标签(Attribute) 授权方式 1 Policy(策略) 2 Role(角色) 3 Scheme(方案) 3 定义权限项 4 实现 Requirement 5 实现授权处理程序 Handler 6 添加授权处理程序 7 添加授权策略 8 控制器配置

  • ASP.NET Core使用JWT自定义角色并实现策略授权需要的接口

    ① 存储角色/用户所能访问的 API 例如 使用 List<ApiPermission> 存储角色的授权 API 列表. 可有可无. 可以把授权访问的 API 存放到 Token 中,Token 也可以只存放角色信息和用户身份信息. /// <summary> /// API /// </summary> public class ApiPermission { /// <summary> /// API名称 /// </summary> pub

  • asp.net core项目授权流程详解

    在上一篇 聊聊 asp.net core 认证和授权 中我们提到了认证和授权的基本概念,以及认证和授权的关系及他们之间的协同工作流程,在这篇文章中,我将通过分析asp.net core 3.1 授权流程的源码给大家介绍asp.net core 框架里面授权流程的具体实现逻辑,本文并非讲解具体的实战应用,建议在使用过asp.net core 授权框架后在来阅读本文收货会更多. 一.授权流程用到的主要的几个接口及类 IAuthorizationService,默认实现类: DefaultAuthor

  • ASP.NET Core使用JWT认证授权的方法

    demo地址: https://github.com/william0705/JWTS 名词解析 认证 : 识别用户是否合法 授权: 赋予用户权限 (能访问哪些资源) 鉴权: 鉴定权限是否合法 Jwt优势与劣势 优势 1. 无状态 token 存储身份验证所有信息 , 服务端不需要保存用户身份验证信息, 减少服务端压力 , 服务端更容易水平扩展, 由于无状态, 又会导致它最大缺点 , 很难注销 2. 支持跨域访问 Cookie是不允许垮域访问的,token支持 3. 跨语言 基于标准化的 JSO

  • Asp.Net Core 企业微信静默授权的实现

    企业微信接口文档 1. 构造授权网页链接 2.回调获取到 Code 通过code+access_token去 请求用户信息 3. 获取access_token 调试准备工作 -->内网穿透+域名 推荐向日葵有免费的,免费的开发测试够用了 域名的配置成可信用 上代码 Demo下载 [ApiController] [Route("api/[controller]")] public class Auth2Controller : ControllerBase { private re

  • ASP.NET Core中Startup类、Configure()方法及中间件详解

    ASP.NET Core 程序启动过程如下 1, Startup 类 ASP.NET Core 应用使用Startup类,按照约定命名为Startup.Startup类: 可选择性地包括ConfigureServices方法以配置应用的服务. 必须包括Configure方法以创建应用的请求处理管道. 当应用启动时,运行时调用ConfigureServices和Configure . Startup 方法体如下 public class Startup { // 使用此方法向容器添加服务 publ

  • ASP.NET Core设置URLs的五种方法

    目录 前言 URL格式 前提条件 方法1 使用环境变量 方法2 使用命令行参数 方法3 使用配置文件 方法4 使用UseUrls 方法5 使用Kestrel 优先级 总结 前言 在使用ASP.NET Core 3.1开发时,需要配置服务器监听的端口和协议,官方帮助文档进行简单说明,文档中提到了4种指定URL的方法 设置ASPNETCORE_URLS 环境变量: 使用dotnet --urls 命令行参数: 使用urls作为键进行配置: 使用UseUrls扩展方法: 为便于讲清楚URLs设置方法,

  • ASP.NET动态添加用户控件的方法

    本文实例讲述了ASP.NET动态添加用户控件的方法.分享给大家供大家参考.具体实现方法如下: 为了让用户控件能ASP.NET页面实现动态添加,首先写一个接口IGetUCable,这个接口有一个函数,返回对象类型是UserControl. using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; /// <summary> /// Summar

  • ASP.NET Core读取Request.Body的正确方法

    前言 相信大家在使用ASP.NET Core进行开发的时候,肯定会涉及到读取Request.Body的场景,毕竟我们大部分的POST请求都是将数据存放到Http的Body当中.因为笔者日常开发所使用的主要也是ASP.NET Core所以笔者也遇到这这种场景,关于本篇文章所套路的内容,来自于在开发过程中我遇到的关于Request.Body的读取问题.在之前的使用的时候,基本上都是借助搜索引擎搜索的答案,并没有太关注这个,发现自己理解的和正确的使用之间存在很大的误区.故有感而发,便写下此文,以作记录

  • [译]ASP.NET Core 2.0 网址重定向的方法

    问题 如何在ASP.NET Core 2.0中实现网址重定向? 答案 新建一个空项目,在Startup.cs文件中,配置RewriteOptions参数并添加网址重定向中间件(UseRewriter): public void Configure(IApplicationBuilder app, IHostingEnvironment env) { var rewrite = new RewriteOptions() .AddRedirect("films", "movies

  • ASP.NET Core MVC获取请求的参数方法示例

    前言 一次HTTP请求,就是一次标准IO操作.请求是I,是输入:响应式O,是输出.任何web开发框架,其实都是在干这两件事: 接受请求并进行解析获取参数 根据参数进行渲染并输出响应内容 所以我们学习一个框架,我认为最首要的是知道如何从请求中获取参数.http请求携带参数的地方主要有下面几个地方: URL Header Body 下面看看ASP.NET Core是如何从这几个位置获取参数的. 通过URL获取参数 通过URL传参是HTTP最最常用的办法.这里简单介绍下URL相关的知识.一个URL主要

  • ASP.NET Core项目中调用WebService的方法

    一.前言 现实生产中,有一些比较老的系统对外提供的接口都是WebService形式的,如果是使用.NET Framework创建的项目调用WebService非常方便,网上有很多代码示例,这里不在讲解,下面我们讲解如何在ASP.NET Core项目里面调用WebService.首先我们需要创建一个WebService项目和一个ASP.NET Core WebApi项目.创建的WebService代码如下: using System.Web.Services; namespace CoreCall

  • Mysql中新建用户及授权的方法分享

    在项目开发的过程中可能需要开放自己的数据库给别人,但是为了安全不能自己服务器里其他数据库同时开放.那么可以新建一个用户,给该用户开放特定数据库权限 测试环境:Centos 6.3和Mysql 5.3 一.新建用户 复制代码 代码如下: //登录MYSQL @>mysql -u root -p @>密码 //创建用户 mysql> insert into mysql.user(Host,User,Password) values("localhost","cp

随机推荐