C#进阶系列——WebApi 身份认证解决方案:Basic基础认证
2021-05-06 00:28
标签:运行 ret dex any namespace nbsp 信息保存 enable blank 正文 在前言里面,我们说了,如果没有启用身份认证,那么任何匿名用户只要知道了我们服务的url,就能随意访问我们的服务接口,从而访问或修改数据库。 可以看到,匿名用户直接通过url就能访问我们的数据接口,最终会发生什么事,大家可以随意畅想。 例如我们直接通过url访问,会返回401 如果是正常流程的请求,带了票据,就OK了。 可以看到,正常流程的请求,会在请求报文的头里面增加Authorization这一项,它的值就是我们的Ticket票据信息。 我们知道,asp.net的认证机制有很多种。对于WebApi也不例外,常见的认证方式有 园子里很多关于WebApi认证的文章,各种认证方式都会涉及到,但感觉都不够细。这里也并不想去研究哪种验证方式适用哪种使用场景,因为博主还是觉得“贪多嚼不烂”,也可能是博主能力所限。对于认证机制,弄懂其中一种,其他的都能融会贯通。此篇就使用Basic基础认证来详细讲解下整个的过程。 我们知道,认证的目的在于安全,那么如何能保证安全呢?常用的手段自然是加密。Basic认证也不例外,主要原理就是加密用户信息,生成票据,每次请求的时候将票据带过来验证。这样说可能有点抽象,我们详细分解每个步骤: 这个基本的原理。下面就按照这个原理来看看每一步的代码如何实现。 首先说下我们的示例场景,上次介绍 CORS 的时候我们在一个解决方案里面放了两个项目Web和WebApiCORS,我们这次还是以这个为例来说明。 这里有一点需要注意的是,因为WebApi默认是没有开启Session的,所以需要我们作一下配置,手动去启用session。如何开启WebApi里面的Session,请参考:http://www.cnblogs.com/tinya/p/4563641.html 正如上面的原理部分说的,登录如果失败,则直接返回;如果成功,则将生成的票据Ticket带到前端,传到主界面/Home/Index,下面,我们就来看看主界面Home/Index。 这里需要说明的是,我们在发送ajax请求之前,通过 XHR.setRequestHeader(‘Authorization‘, ‘BasicAuth ‘ + Ticket); 这一句向请求的报文头里面增加票据信息。就是因为这里加了这一句,所以才有我们下图中的红线部分: 我们看到,上面的/Home/Index页面里面发送了ajax请求去访问服务的 http://localhost:27221/api/Charging/GetAllChargingData 这个接口,那么我们在WebApi里面怎么去验证这个请求和合法的请求呢?接下来我们重点看看验证的这个过程。 增加了特性标注之后,每次请求这个API里面的接口之前,程序会先进入到我们override过的 OnAuthorization() 方法里面,验证通过之后,才会进到相应的方法里面去执行,否则返回401。 通过上面的几步,基本就能达到我们想要的身份认证的效果,但是总是感觉不太方便,主要不太方便的点有以下几个。 关于以上两点,我们优化下 在API里面加一个公共的父类,在父类上面标注 [RequestAuthorize] 即可。 注意:我们登录的请求是不需要验证的,因为登录的时候还没有产生票据,所以登录的API不能够继承 BaseApiController 还记得我们在 JS组件系列——封装自己的JS组件,你也可以 这篇里面介绍的增加ajax的error事件的公共处理方法吗?我们是否也可以通过同样的机制去增加这个呢。新建一个文件Jquery_ajax_extention.js 引用这个js后再发送ajax不必在每个请求的beforeSend里面写了。 如果我们某些方法不想使用验证,使得它可以让匿名用户访问,我们可以在方法的上面加特性标注 [AllowAnonymous] ,申明该方法运行匿名访问。比如: 以上结合一个实例讲解了下Basic认证的实现原理以及简单使用,本文观点都是来自博主自己的理解,如果有不全面的地方,还望园友们斧正。 C#进阶系列——WebApi 身份认证解决方案:Basic基础认证 标签:运行 ret dex any namespace nbsp 信息保存 enable blank 原文地址:http://www.cnblogs.com/zxh1919/p/7669943.html一、为什么需要身份认证
1、我们不加身份认证,匿名用户可以直接通过url随意访问接口:
2、增加了身份认证之后,只有带了我们访问票据的请求才能访问我们的接口。
二、Basic基础认证的原理解析
1、常见的认证方式
2、Basic基础认证原理
三、Basic基础认证的代码示例
1、登录过程
1.1、Web前端
body>
div style="text-align:center;">
div>用户名:input type="text" id="txt_username" />div>
div>密 码:input type="password" id="txt_password" />div>
div>input type="button" value="登录" id="btn_login" class="btn-default" />div>
div>
body>
$(function () {
$("#btn_login").click(function () {
$.ajax({
type: "get",
url: "http://localhost:27221/api/User/Login",
data: { strUser: $("#txt_username").val(), strPwd: $("#txt_password").val() },
success: function (data, status) {
if (status == "success") {
if (!data.bRes){
alert("登录失败");
return;
}
alert("登录成功"); //登录成功之后将用户名和用户票据带到主界面
window.location = "/Home/Index?UserName=" + data.UserName + "&Ticket=" + data.Ticket;
}
},
error: function (e) {
},
complete: function () {
}
});
});
});
1.2、登录的API接口
public class UserController : ApiController
{
///
2、/Home/Index主界面
public class HomeController : Controller
{
// GET: Home
public ActionResult Index(string UserName, string Ticket)
{
ViewBag.UserName = UserName;
ViewBag.Ticket = Ticket;
return View();
}
}
html>
head>
meta name="viewport" content="width=device-width" />
title>Indextitle>
script src="~/Content/jquery-1.9.1.js">script>
link href="~/Content/bootstrap/css/bootstrap.css" rel="stylesheet" />
script src="~/Content/bootstrap/js/bootstrap.js">script>
script src="~/Scripts/Home/Index.js">script>
script type="text/javascript">
//打开页面的时候保存票据信息
var UserName = ‘@ViewBag.UserName‘;
var Ticket = ‘@ViewBag.Ticket‘;
script>
head>
body>
div>当前登录用户:‘@ViewBag.UserName‘div>
div id="div_test">
div>
body>
html>
$(function () {
$.ajax({
type: "get",
url: "http://localhost:27221/api/Charging/GetAllChargingData",
data: {},
beforeSend: function (XHR) {
//发送ajax请求之前向http的head里面加入验证信息
XHR.setRequestHeader(‘Authorization‘, ‘BasicAuth ‘ + Ticket);
},
success: function (data, status) {
if (status == "success") {
$("#div_test").html(data);
}
},
error: function (e) {
$("#div_test").html("Error");
},
complete: function () {
}
});
});
3、WebApiCORS验证部分(重点)
3.1、在WebApiCORS项目里面自定义一个类RequestAuthorizeAttribute,去继承我们的AuthorizeAttribute这个类。然后重写OnAuthorization方法,在这个方法里面取到请求头的Ticket信息,然后校验用户名密码是否合理。
///
3.2、在具体的Api接口增加我们上面自定义类的特性
[RequestAuthorize]
public class ChargingController : ApiController
{
///
四、优化
1、解决API的问题
namespace WebApiCORS.Controllers
{
[RequestAuthorize]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class BaseApiController : ApiController
{
}
}
namespace WebApiCORS.Controllers
{
public class ChargingController : BaseApiController
{
///
2、解决ajax的问题
(function ($) {
//1.得到$.ajax的对象
var _ajax = $.ajax;
$.ajax = function (options) {
//2.每次调用发送ajax请求的时候定义默认的error处理方法
var fn = {
error: function (XMLHttpRequest, textStatus, errorThrown) {
toastr.error(XMLHttpRequest.responseText, ‘错误消息‘, { closeButton: true, timeOut: 0, positionClass: ‘toast-top-full-width‘ });
},
success: function (data, textStatus) { },
beforeSend: function (XHR) { },
complete: function (XHR, TS) { }
}
//3.扩展原生的$.ajax方法,返回最新的参数
var _options = $.extend({}, {
error: function (XMLHttpRequest, textStatus, errorThrown) {
fn.error(XMLHttpRequest, textStatus, errorThrown);
},
success: function (data, textStatus) {
fn.success(data, textStatus);
},
beforeSend: function (XHR) {
XHR.setRequestHeader(‘Authorization‘, ‘BasicAuth ‘ + Ticket);
fn.beforeSend(XHR);
},
complete: function (XHR, TS) {
fn.complete(XHR, TS);
}
}, options);
//4.将最新的参数传回ajax对象
_ajax(_options);
};
})(jQuery);
3、解决特殊不想使用验证的方法
public class ChargingController : BaseApiController
{
///
五、总结
文章标题:C#进阶系列——WebApi 身份认证解决方案:Basic基础认证
文章链接:http://soscw.com/index.php/essay/82975.html