1、WebApi中为什么需要身份认证

我们在使用WebApi的时候,都是通过URL去获取数据。也就是说,任何人只要知道了URL地址,就能随意的访问后台的服务接口,就可以访问或者修改数据库数据了,这样就会导致很严重的后果。

1、我们不加身份认证,匿名用户可以直接通过url随意访问接口:

2、增加了身份认证之后,只有带了票据的请求才能访问对应的接口。

2、常见的认证方式

WebApi中常见的认证方式有如下几种:

  • FORM身份验证
  • 集成WINDOWS验证
  • Basic基础认证
  • Digest摘要认证

3、Basic基础认证

1、Basic基础认证原理

Basic认证的基本原理就是加密用户信息生成Ticket,每次请求后端API接口的时候把生成的Ticket信息加到http请求的头部传给后端进行验证。具体步骤如下:

1、登录的时候验证用户名和密码,如果验证通过,则将用户名和密码按照一定的规则生成加密后的票据信息Ticket,然后将Ticket传递到前端。

2、如果登录成功,前端定义一个全局的变量接收API接口返回的Ticket信息。

3、前端界面再次发起ajax请求后端API接口的时候,将Ticket信息加入到HTTP请求的Head里面,将Ticket信息随着http请求一起发送到后端API接口。

4、在后端的WebApi服务中定义一个类,该类继承自AuthorizeAttribute类,然后重新父类里面的OnAuthorization方法,在OnAuthorization方法里面,通过actionContext参数取得http请求的Head,从Head里面可以获取前端传递过来的Ticket信息。将Ticket解密得到用户名和密码,然后验证用户名和密码是否正确。如果正确,表示验证通过。如果不正确,则返回401未授权的错误。

4、Basic基础认证示例代码

假设我们要访问Users控制器的Get接口,该接口方法返回int类型的List集合。

1、登录的API接口

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(""))
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(, account, DateTime.Now,
DateTime.Now.AddHours(), 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();
list.Add();
list.Add();
list.Add();
list.Add();
return Json<List<int>>(list);
}
}
}

在Login方法上面添加 [AllowAnonymous]特性,表示允许匿名登录。

2、基础认证接口

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 !=
|| actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != )
{
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[];
string strPwd = array[];
// 真实生产环境中应该用解密的用户名和密码去数据库验证,这里为了演示方便
// 假定用户名是Admin,密码是123456
if(strUser.Equals("Admin")&&strPwd.Equals(""))
{
return true;
}
else
{
return false;
}
}
}
}

3、前端代码

<!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接口要配置允许跨域访问。

4、优化

每增加一个控制器,都需要在相应的控制器上面加[BasicAuthorize]特性,可以定义一个公共的控制器父类,该父类继承自ApiController,然后其他控制器继承该父类。

Web API(七):Basic基础认证的更多相关文章

  1. C#进阶系列——WebApi 身份认证解决方案:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...

  2. WebApi身份认证解决方案:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...

  3. C#进阶系列——WebApi身份认证解决方案:Basic基础认证 (转)

    http://www.cnblogs.com/landeanfen/p/5287064.html 前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人 ...

  4. WebApi 身份认证解决方案:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...

  5. c# WebApi之身份验证:Basic基础认证

    为什么需要身份认证 身份认证是为了提高接口访问的安全性,如果没有身份验证,那么任何匿名用户只要知道服务器的url,就可以随意访问服务器,从而访问或者操作数据库,这会是很恐怖的事. 什么是Basic基础 ...

  6. (转)C# WebApi 身份认证解决方案:Basic基础认证

    原文地址:http://www.cnblogs.com/landeanfen/p/5287064.html 阅读目录 一.为什么需要身份认证 二.Basic基础认证的原理解析 1.常见的认证方式 2. ...

  7. #进阶系列——WebApi 身份认证解决方案:Basic基础认证

    阅读目录 一.为什么需要身份认证 二.Basic基础认证的原理解析 1.常见的认证方式 2.Basic基础认证原理 三.Basic基础认证的代码示例 1.登录过程 2./Home/Index主界面 3 ...

  8. Asp.Net MVC 4 Web API 中的安全认证-使用OAuth

    各种语言实现的oauth认证: http://oauth.net/code/ 上一篇文章介绍了如何使用基本的http认证来实现asp.net web api的跨平台安全认证. 这里说明一个如何使用oa ...

  9. 为Asp.Net Web Api添加Http基本认证

    Asp.net Web Api提供了RESTFul web服务的编程接口.默认RESTFul 服务没有提供任何验证或者基于角色的验证,这显然不适合Put.Post.Delete这些操作.Aps.net ...

随机推荐

  1. C#基础第八天-作业答案-设计类-面向对象方式实现两个帐户之间转账

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. U811.1接口EAI系列之六--物料上传--VB语言

    1. 业务系统同步U811.1存货档案通用方法. 2.具体代码处理如下: 作者:王春天 2013-11-06 地址:http://www.cnblogs.com/spring_wang/p/34098 ...

  3. springboot 项目单元测试

    项目结构如下 1 引入测试的 maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> & ...

  4. 设计模式-建造者模式(Builder Pattern)

    建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式要求建造过程中是稳定的. Android 用到的 Builder 模 ...

  5. Eclipse中如何安装和使用GrepCode插件 (转)

    GrepCode(GC)Eclipse插件允许Eclipse用户在Eclipse IDE中搜索由GrepCode提供的工厂类.本教程介绍如何安装和使用插件.使用Eclipse3.5(Galileo)的 ...

  6. eclipse再见,android studio 新手新手教程(一)基本设置

    写在前面: 作为一个刚半仅仅脚踏入android开发的新手,在使用eclipse开发了两个自我感觉不甚成熟的商城类app之后.遇到了一些问题,总结为例如以下: 1,代码复用性. findviewByI ...

  7. Multi-Cloud & Kubernetes: Cloud Academy November 2018 Data Report

    https://cloudacademy.com/research/multi-cloud-kubernetes-devops-cloud-academy-data-report-nov-18/ No ...

  8. Django admin 常用方法

    1.调整页面头部显示内容和页面标题 #admin.py admin.site.site_header = '广告业务系统' admin.site.site_title = '广告业务系统'

  9. 分类算法----k近邻算法

    K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的 ...

  10. hdu3038(种类并查集,推荐)

    题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的?? 很有意思的一道题目,要是没有做过种类并查集,我肯定会以为这种题目是线段树题目...... 思路:我 ...