写在前面:

如果webapi接口没有身份认证,那么所有知道接口url的用户都可以随意访问接口,从而查询或者修改数据库,

那么问题就来了,如果我们不想让所有人都调用我们的接口,那么就需要加上一层验证,只让那些带着正确票据信息的请求来访问webapi接口

跟mvc一样,webapi大多通过附加Authorize特性来实现验证票据信息进行授权,在做这些之前我们先了解一下这个所谓的Authorize的特性:

首先我们需要用的webApi下的授权筛选AuthorizeAttribute为System.Web.Http.AuthorizeAttribute, 而不是Mvc下用的System.Web.Mvc.AuthorizeAttribute,这点要分清楚

那么就来说一下AuthorizeAttribute类

1,AuthorizeAttribute类有一个IsAuthorized方法,用来指示指定的访问是否通过授权, 我们通过该方法为访问请求进行授权

2,AuthorizeAttribute类中的OnAuthorization方法是一个可以进行重写的方法,该方法的作用就是验证身份票据是否通过,如果验证通过,我们便通过IsAuthorized方法为该请求进行授权,如果不通过则通过HandleUnauthorizedRequest方法处理授权失败的请求

3,上面说到通过HandleUnauthorizedRequest处理授权失败的请求,那么HandleUnauthorizedRequest这个方法便是我们可以重写的处理授权失败的请求进行的操作

想必看到这里,大家应该明白了我们用这种方式进行身份票据认证的大概流程,那么我们接下来说一下具体实现的方法:

首先在webapi项目中我们新建一个类,去继承AuthorizeAttribute,重写我们上面说到的OnAuthorizationHandleUnauthorizedRequest方法:

public class ZyTestAuthorize : AuthorizeAttribute
{
/// <summary>
/// 重写基类的验证方式,加入ticket验证
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//获取身份票据
var authorization = actionContext.Request.Headers.Authorization; if ((authorization != null) && (authorization.Parameter != null))
{
//解密用户ticket,并校验是否正确
var encryptTicket = authorization.Parameter;
if (ValidateTicket(encryptTicket))
{
base.IsAuthorized(actionContext);//为此请求授权
}
else
{
HandleUnauthorizedRequest(actionContext);
}
}
//如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
else
{
var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
if (isAnonymous) base.OnAuthorization(actionContext);
else HandleUnauthorizedRequest(actionContext);
}
} /// <summary>
/// 校验票据是否正确
/// </summary>
/// <param name="encryptToken"></param>
/// <returns></returns>
private bool ValidateTicket(string encryptToken)
{
bool flag = false;
try
{
//从数据库取出对应票据 判断是否对应 切是否在有效期内
//--------------省略此处数据库判断------------
//如果验证通过 返回true
return true;
}
catch (Exception ex) { }
return flag;
} /// <summary>
/// 重写处理授权失败方法
/// </summary>
/// <param name="filterContext"></param>
protected override void HandleUnauthorizedRequest(HttpActionContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext); var response = filterContext.Response = filterContext.Response ?? new HttpResponseMessage();
response.StatusCode = HttpStatusCode.Forbidden;
//Result类 可自行创建,具体为返回的content信息
var content = new Result
{
success = false,
errs = new[] { "未得授权,禁止访问" }
};
response.Content = new StringContent(Json.Encode(content), Encoding.UTF8, "application/json");
}
}

接下来需要在我们的具体的webapi接口上添加我们刚刚写好的类的特性:

    [ZyTestAuthorize]
public class ZyTestController : ApiController
{
[AllowAnonymous]
public string Get()
{
return "23333";
}
[HttpPost]
public ResultDataModel Post([FromBody] TestModel model)
{
ResultDataModel rm = new ResultDataModel();
rm.code = "code";
rm.datas = JsonConvert.SerializeObject(model);
rm.msg = "msg";
return rm;
}
}

以上这些便是添加身份票据验证的具体实现  

但是我们发现上面这个示例的webapi接口中除了我们刚才写的ZyTestAuthorize这个类的特性还有一个AllowAnonymous特性,这个特性是用来干什么的呢

有些时候 我们的webapi中其中的某些接口是不想添加身份验证的,那么AllowAnonymous特性就是解决这个问题的,在方法上添加该特性,则会绕过身份验证可直接进行访问

以上便是我们今天所要说的webapi身份认证的具体实现方式,下面我们看一下js的具体调用方式:

$("#btnTest").click(function () {
var model = { name: "name", value: "val" };//post数据
var token = "233333";//身份票据
$.ajax({
url: "http://localhost:2643/ZyTest",
type: "POST",
data: model,
//在beforeSend方法中设置身份票据
beforeSend: function (request) {
request.setRequestHeader('Authorization', 'Bearer ' + token);
},
success: function (json) {
alert("ok");
$("#lbTest").text(json);
},
error: function (a, b) {
alert("error:" + JSON.stringify(a));
}
});
});

使用C#在后台调用的一种方式:

使用await为了接收到返回结果,ObjectContent需要引用System.Net.Http.Formatting

    private async void ZyTest()
{
TestModel m = new TestModel();
m.Name = "zy";
m.Value = "alex"; var c = new HttpClient();
c.BaseAddress = new Uri("http://localhost:2643");
c.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
HttpContent content = new ObjectContent<TestModel>(m, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
var response = await c.PostAsync("/ZyTest", content);
string result = response.Content.ReadAsStringAsync().Result;
}

以上。

本文是在工作需要的时候,网上搜集文章资料加上自己的浅薄见解所整理出来的,如果有错误或者不合理的地方,还请各位不吝赐教,在下必洗耳恭听。

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

后续补充:

如果需要在特定的api中获取当前用户的信息

var Authorization = Request.Headers.Authorization;

目前没找到更好的办法来实现 只能用上面句代码来获取当前请求的token信息 重新解析找到用户信息。

WebApi 通过身份票据进行认证授权的具体实现的更多相关文章

  1. ASP.NET Core WebAPI中使用JWT Bearer认证和授权

    目录 为什么是 JWT Bearer 什么是 JWT JWT 的优缺点 在 WebAPI 中使用 JWT 认证 刷新 Token 使用授权 简单授权 基于固定角色的授权 基于策略的授权 自定义策略授权 ...

  2. ASP.NET WEBAPI 的身份验证和授权

    定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...

  3. [认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)

    0 目录 认证授权系列:http://www.cnblogs.com/linianhui/category/929878.html 1 什么是OIDC? 看一下官方的介绍(http://openid. ...

  4. [认证授权] 5.OIDC(OpenId Connect)身份认证授权(扩展部分)

    在上一篇[认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)中解释了OIDC的核心部分的功能,即OIDC如何提供id token来用于认证.由于OIDC是一个协议族,如果 ...

  5. [认证授权] 5.OIDC(OpenId Connect)身份认证(扩展部分)

    在上一篇[认证授权] 4.OIDC(OpenId Connect)身份认证(核心部分)中解释了OIDC的核心部分的功能,即OIDC如何提供id token来用于认证.由于OIDC是一个协议族,如果只是 ...

  6. [认证授权] 4.OIDC(OpenId Connect)身份认证(核心部分)

    1 什么是OIDC? 看一下官方的介绍(http://openid.net/connect/): OpenID Connect 1.0 is a simple identity layer on to ...

  7. 一站式WebAPI与认证授权服务

    保护WEBAPI有哪些方法? 微软官方文档推荐了好几个: Azure Active Directory Azure Active Directory B2C (Azure AD B2C)] Ident ...

  8. asp.net core 3.1多种身份验证方案,cookie和jwt混合认证授权

    开发了一个公司内部系统,使用asp.net core 3.1.在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据.并且只是几个简单的接口不准备再重新部署一 ...

  9. 关于WEB Service&WCF&WebApi实现身份验证之WebApi篇

    之前先后总结并发表了关于WEB Service.WCF身份验证相关文章,如下: 关于WEB Service&WCF&WebApi实现身份验证之WEB Service篇. 关于WEB S ...

随机推荐

  1. jgit - java实现git操作

    在做一个项目中需要用到远程仓库,本来想使用svn的,但是svn的java api网上的资料很少,而且与git相比,svn显得笨重且不方便,因此放弃了svn转而使用git.java git api - ...

  2. Activity has leaked window that was originally added(以解决)

     在编写Android程序的时候,遇到一个隐藏性问题.仔细查看LogCat,错误信息如下: 10-31 13:03:34.549: ERROR/WindowManager(444): Activi ...

  3. I-O流概念认知升级

    在文件操作基础入门中,我们提到了流的 概念,这篇我们将更多的介绍流这个东西,以及C的I/O相关知识 现在,我们从C程序员最熟悉的printf函数开始学习I/O流. 我们对printf函数一直是很喜爱的 ...

  4. phpcms V9二级目录下分页路径不正确问题的彻底解决方法

    在用phpcms V9做二次开发的时候,我们有时候会把一个栏目生成到根目录下,而且这个栏目又有子栏目,我们生成静态的时候分页会出现问题,就是分页的路径的地址错误.有一种解决方法就是,把这个栏目生成动态 ...

  5. SP104 HIGH - Highways

    vjudge luogu 题意 就是要你求无向图的生成树个数.\(n\le 12\),保证答案不爆\(long long\). sol 矩阵树定理直接上. 如果怕掉精可以写整数意义下的高斯消元,需要辗 ...

  6. LINUX TCP套接字详细配置

    提高服务器的负载能力,是一个永恒的话题.在一台服务器CPU和内存资源额定有限的情况下,最大的压榨服务器的性能,是最终的目的.要提高 Linux系统下的负载能力,可以先启用Apache的Worker模式 ...

  7. gradle wrapper 简单使用

    其实就是对于gradle 的一个包装,保证了项目版本的一致,同时减少配置   1. 生成wrapper // 使用gradle wrapper 命令 gradle wrapper 输出效果如下: [r ...

  8. 《大教堂和集市》笔记——为什么一个本科生业余作品却成了全世界最流行的操作系统之一Linux?

    1. Eric Raymond有一篇著名文章<大教堂和集市>(The Cathedral and the Bazaar). 他说,世界上的建筑可以分两种:一种是集市,天天开放在那里,从无到 ...

  9. Tomcat起了一个测试桩,调用该测试桩无响应

    有时在测试新业务流程时因为涉及多个不同接口的调用,而这些被调用的服务端因为网络权限或开发进度问题暂时对我们不可达,那么我们可以通过模拟接口返回来完成我们新业务的测试.这次碰到的问题是我明明起了该测试桩 ...

  10. Nginx httpS server配置

    Nginx httpS 配置 配置同时支持http和httpS协议: server { listen ; #backlog:每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包 ...