一、webapi中为什么需要身份认证 我们在使用WEBapi的时候,都是通过URL去获取数据。也就是说,任何人只要知道了URL地址,就能随意的访问后台的服务接口,就可以访问或者修改数
我们在使用WEBapi的时候,都是通过URL去获取数据。也就是说,任何人只要知道了URL地址,就能随意的访问后台的服务接口,就可以访问或者修改数据库数据了,这样就会导致很严重的后果。
1、我们不加身份认证,匿名用户可以直接通过url随意访问接口:
2、增加了身份认证之后,只有带了票据的请求才能访问对应的接口。
WebApi中常见的认证方式有如下几种:
Basic认证的基本原理就是加密用户信息生成Ticket,每次请求后端API接口的时候把生成的Ticket信息加到Http请求的头部传给后端进行验证。具体步骤如下:
假设我们要访问Users控制器的Get接口,该接口方法返回int类型的List集合。
using Newtonsoft.JSON;
using System;
using System.Collections.Generic;
using System.Linq;
using System.net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Security;
using WebApiBasicAuthorize.CustomerAttribute;
using WebApiBasicAuthorize.Entity;
namespace WebApiBasicAuthorize.Controllers
{
[BasicAuthorize]
public class UsersController : ApiController
{
/// <summary>
/// 允许匿名登录
/// </summary>
/// <param name="account"></param>
/// <param name="passWord"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet]
public IHttpActionResult Login(string account,string password)
{
ReturnValueEntity entity = new ReturnValueEntity();
// 真实生产环境中要去数据库校验account和password
if (account.ToUpper().Trim().Equals("ADMIN") && password.Trim().Equals("123456"))
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, account, DateTime.Now,
DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", account, password),
FormsAuthentication.FormsCookiePath);
var result = new { Result = true, Ticket = FormsAuthentication.Encrypt(ticket) };
entity.Result = true;
entity.Ticket = FormsAuthentication.Encrypt(ticket);
}
else
{
entity.Result = false;
entity.Ticket = "";
}
return json<ReturnValueEntity>(entity);
}
[HttpGet]
public IHttpActionResult Get()
{
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list.Add(5);
return Json<List<int>>(list);
}
}
}
在Login方法上面添加 [AllowAnonymous]特性,表示允许匿名登录。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Security;
namespace WebApiBasicAuthorize.CustomerAttribute
{
/// <summary>
/// 自定义特性继承自AuthorizeAttribute
/// </summary>
public class BasicAuthorizeAttribute:AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
// 从当前http请求Request对象的头部信息里面获取Authorization属性
var authorization = actionContext.Request.Headers.Authorization;
// 判断控制器获取action方法上面是否有AllowAnonymousAttribute特性,如果有,则允许匿名登录
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0
|| actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0)
{
base.OnAuthorization(actionContext);
}
else if (authorization != null && authorization.Parameter != null)
{
// 验证用户逻辑
if (ValidateTicket(authorization.Parameter))
{
// 验证通过
base.IsAuthorized(actionContext);
}
else
{
this.HandleUnauthorizedRequest(actionContext);
}
}
else
{
// 返回401没有授权的状态码
this.HandleUnauthorizedRequest(actionContext);
}
}
/// <summary>
/// 验证Ticket信息
/// </summary>
/// <param name="encryptTicket"></param>
/// <returns></returns>
private bool ValidateTicket(string encryptTicket)
{
// 解密Ticket
var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;
// 从Ticket里面获取用户名和密码
int index = strTicket.IndexOf("&");
//string strUser=strTicket
string[] array = strTicket.Split('&');
string strUser = array[0];
string strPwd = array[1];
// 真实生产环境中应该用解密的用户名和密码去数据库验证,这里为了演示方便
// 假定用户名是Admin,密码是123456
if(strUser.Equals("Admin")&&strPwd.Equals("123456"))
{
return true;
}
else
{
return false;
}
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>权限认证</title>
<script src="Jquery-1.10.2.min.js"></script>
<script>
// 定义全局的ticket变量,用来保存登录成功以后的Ticket值
var ticket;
window.onload=function(){
};
function Login(){
$.ajax({
url:"http://localhost:20033/api/users?account="+$("#acc").val().trim()+"&password="+$("#pwd").val().trim(),
type:"Get",
dataType:"json",
"headers": {
"Content-Type": "application/json",
"cache-control": "no-cache"
},
success:function(data){
if(result.Result){
ticket=data.Ticket;
}else{
alert("失败");
}
},
error:function(data){
alert(data);
}
});
};
function Test(){
alert(ticket);
$.ajax({
url:'http://localhost:20033/api/users',
type:"Get",
dataType:"json",
beforeSend:function(XHR){
//发送ajax请求之前向http的head里面加入验证信息
XHR.setRequestHeader('Authorization','BasicAuth '+ticket);
},
success:function(data){
alert(data);
},
error:function(data){
alert(data);
}
});
};
</script>
</head>
<body>
<div>
<div>
<label>用户名:</label>
<input type="text" id="acc">
</div>
<div>
<label>密码:</label>
<input type="password" id="pwd">
</div>
<div>
<input type="button" id="btnLogin" onclick="Login()" value="登录">
</div>
<div>
<input type="button" id="GetAccount" onclick="Test()" value="测试">
</div>
</div>
</body>
</html>
这里需要说明的是,我们在发送ajax请求之前,通过XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket); 这句向http请求的Head里面添加Ticket信息。
通过上面的几步就可以达到Basic认证的效果了。
注意:后端的WebApi接口要配置允许跨域访问。
每增加一个控制器,都需要在相应的控制器上面加[BasicAuthorize]特性,可以定义一个公共的控制器父类,该父类继承自ApiController,然后其他控制器继承该父类。
到此这篇关于Web API身份认证解决方案之Basic基础认证的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。
--结束END--
本文标题: WebAPI身份认证解决方案之Basic基础认证
本文链接: https://www.lsjlt.com/news/142299.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2023-05-21
2023-05-21
2023-05-21
2023-05-21
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0