WebApi 身份认 Basic基础认证
<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 () {
}
});
});
});
public class UserController : ApiController
{
/// <summary>
/// 用户登录
/// </summary>
/// <param name="strUser"></param>
/// <param name="strPwd"></param>
/// <returns></returns>
[HttpGet]
public object Login(string strUser, string strPwd)
{
if (!ValidateUser(strUser, strPwd))
{
return new { bRes = false };
}
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, strUser, DateTime.Now,
DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", strUser, strPwd),
FormsAuthentication.FormsCookiePath);
//返回登录结果、用户信息、用户验证票据信息
var oUser = new UserInfo { bRes = true, UserName = strUser, Password = strPwd, Ticket = FormsAuthentication.Encrypt(ticket) };
//将身份信息保存在session中,验证当前请求是否是有效请求
HttpContext.Current.Session[strUser] = oUser;
return oUser;
} //校验用户名密码(正式环境中应该是数据库校验)
private bool ValidateUser(string strUser, string strPwd)
{
if (strUser == "admin" && strPwd == "123456")
{
return true;
}
else
{
return false;
}
}
} public class UserInfo
{
public bool bRes { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Ticket { get; set; }
}
如何开启WebApi里面的Session,请参考:http://www.cnblogs.com/tinya/p/4563641.html
正如上面的原理部分说的,登录如果失败,则直接返回;如果成功,则将生成的票据Ticket带到前端,传到主界面/Home/Index,下面,我们就来看看主界面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>Index</title>
<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 () {
}
});
});
继承我们的AuthorizeAttribute这个类。然后重写OnAuthorization方法,在这个方法里面取到请求头的Ticket信息,然后校验用户名密码是否合理。
/// <summary>
/// 自定义此特性用于接口的身份验证
/// </summary>
public class RequestAuthorizeAttribute : AuthorizeAttribute
{
//重写基类的验证方式,加入我们自定义的Ticket验证
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//从http请求的头里面获取身份验证信息,验证是否是请求发起方的ticket
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);
}
} //校验用户名密码(正式环境中应该是数据库校验)
private bool ValidateTicket(string encryptTicket)
{
//解密Ticket
var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData; //从Ticket里面获取用户名和密码
var index = strTicket.IndexOf("&");
string strUser = strTicket.Substring(0, index);
string strPwd = strTicket.Substring(index + 1); if (strUser == "admin" && strPwd == "123456")
{
return true;
}
else
{
return false;
}
}
}
[RequestAuthorize]
public class ChargingController : ApiController
{
/// <summary>
/// 得到所有数据
/// </summary>
/// <returns>返回数据</returns>
[HttpGet]
public string GetAllChargingData()
{
return "Success";
} /// <summary>
/// 得到当前Id的所有数据
/// </summary>
/// <param name="id">参数Id</param>
/// <returns>返回数据</returns>
[HttpGet]
public string GetAllChargingData(string id)
{
return "ChargingData" + id;
} }
增加了特性标注之后,每次请求这个API里面的接口之前,程序会先进入到我们override过的 OnAuthorization() 方法里面,验证通过之后,才会进到相应的方法里面去执行,否则返回401。
优化
namespace WebApiCORS.Controllers
{
[RequestAuthorize]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class BaseApiController : ApiController
{
}
}
namespace WebApiCORS.Controllers
{
public class ChargingController : BaseApiController
{
/// <summary>
/// 得到所有数据
/// </summary>
/// <returns>返回数据</returns>
[HttpGet]
public string GetAllChargingData()
{
return "Success";
} /// <summary>
/// 得到当前Id的所有数据
/// </summary>
/// <param name="id">参数Id</param>
/// <returns>返回数据</returns>
[HttpGet]
public string GetAllChargingData(string id)
{
return "ChargingData" + id;
}
}
}
解决ajax的问题
还记得我们在 JS组件系列——封装自己的JS组件,你也可以 这篇里面介绍的增加ajax的error事件的公共处理方法吗?我们是否也可以通过同样的机制去增加这个呢。新建一个文件Jquery_ajax_extention.js
(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);
解决特殊不想使用验证的方法
public class ChargingController : BaseApiController
{
/// <summary>
/// 得到所有数据
/// </summary>
/// <returns>返回数据</returns>
[HttpGet]
public string GetAllChargingData()
{
return "Success";
} /// <summary>
/// 得到当前Id的所有数据
/// </summary>
/// <param name="id">参数Id</param>
/// <returns>返回数据</returns>
[HttpGet]
[AllowAnonymous]
public string GetAllChargingData(string id)
{
return "ChargingData" + id;
}
}
WebApi 身份认 Basic基础认证的更多相关文章
- C#进阶系列——WebApi 身份认证解决方案:Basic基础认证
前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...
- WebApi身份认证解决方案:Basic基础认证
前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...
- C#进阶系列——WebApi身份认证解决方案:Basic基础认证 (转)
http://www.cnblogs.com/landeanfen/p/5287064.html 前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人 ...
- WebApi 身份认证解决方案:Basic基础认证
前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...
- c# WebApi之身份验证:Basic基础认证
为什么需要身份认证 身份认证是为了提高接口访问的安全性,如果没有身份验证,那么任何匿名用户只要知道服务器的url,就可以随意访问服务器,从而访问或者操作数据库,这会是很恐怖的事. 什么是Basic基础 ...
- (转)C# WebApi 身份认证解决方案:Basic基础认证
原文地址:http://www.cnblogs.com/landeanfen/p/5287064.html 阅读目录 一.为什么需要身份认证 二.Basic基础认证的原理解析 1.常见的认证方式 2. ...
- #进阶系列——WebApi 身份认证解决方案:Basic基础认证
阅读目录 一.为什么需要身份认证 二.Basic基础认证的原理解析 1.常见的认证方式 2.Basic基础认证原理 三.Basic基础认证的代码示例 1.登录过程 2./Home/Index主界面 3 ...
- Web API(七):Basic基础认证
1.WebApi中为什么需要身份认证 我们在使用WebApi的时候,都是通过URL去获取数据.也就是说,任何人只要知道了URL地址,就能随意的访问后台的服务接口,就可以访问或者修改数据库数据了,这样就 ...
- HTTP基础认证Basic Authentication
HTTP基础认证Basic Authentication Basic Authentication是一种HTTP访问控制方式,用于限制对网站资源的访问.这种方式不需要Cookie和Session,只需 ...
随机推荐
- [转]Windows系统下批量重命名文件(bat命令版本)
原文地址:https://jingyan.baidu.com/article/6dad507524bdcba122e36e44.html 我们有时候会遇到大量文件需要重命名,Windows系统下右键菜 ...
- Linux_CentOS 打包压缩和别名管理
Linux 打包压缩命令 目前 linux 中打包和压缩的命令很多,最常用的方法有 zip.gzip.bzip2.xz.tar 1.zip 压缩包 1.制作 zip -r public.zip pub ...
- python制作简单excel统计报表1之with的简单用法
# coding=utf-8 def open_file(): """使用with打开一个文件""" # 普通操作文件方法 # f = op ...
- cJSON笔记
github地址: https://github.com/DaveGamble/cJSON 需要将cJSON.h 和 cJSON.c拷贝到路径下,并且连接所需库文件 -lm 步骤:1.先将普通的jso ...
- 【PromQL】prometheus查询语言
常用查询: https://songjiayang.gitbooks.io/prometheus/content/exporter/nodeexporter_query.html group by 操 ...
- express url跳转(重定向)的实现:res.location() res.redirect()
Express 是一个基于Node.js 实现的web框架,其响应HTTP请求的response对象中有两个响应url跳转方法res.location() res.redirect(),可以实现301 ...
- TortoiseSVN安装和使用(转)
http://blog.csdn.net/Zhihua_W/article/details/64904692?locationNum=2&fps=1 https://www.cnblogs.c ...
- 数据挖掘经典算法PrefixSpan的一个简单Python实现
前言 用python实现了一个没有库依赖的"纯" py-based PrefixSpan算法. Github 仓库 https://github.com/Holy-Shine/Pr ...
- idea创建自定义代码块
1.File——>settings 2.找到Editor——>live Templates,点击加号+ 3.创建group或直接创建,我这里创建了一个user组,然后在user组里面添加l ...
- pycharm设置开发模板/字体大小/背景颜色(3)
一.pycharm设置字体大小/风格 选择 File –> setting –> Editor –> Font ,可以看到如上界面,可以根据自己的喜好随意调整字体大小,字体风格,文字 ...