Web API身份认证解决方案之Basic基础认证

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

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

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

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

二、常见的认证方式

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

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

三、Basic基础认证

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未授权的错误。

四、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("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]特性,表示允许匿名登录。

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 != 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;
            }
        }
    }
}

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基础认证的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET Forms身份认证

    asp.net程序开发,用户根据角色访问对应页面以及功能. 项目结构如下图: 根目录 Web.config 代码: <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细消息,请访问 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <system.web> &

  • 在ASP.NET Core中实现一个Token base的身份认证实例

    以前在web端的身份认证都是基于Cookie | Session的身份认证, 在没有更多的终端出现之前,这样做也没有什么问题,但在Web API时代,你所需要面对的就不止是浏览器了,还有各种客户端,这样就有了一个问题,这些客户端是不知道cookie是什么鬼的. (cookie其实是浏览器搞出来的小猫腻,用来保持会话的,但HTTP本身是无状态的, 各种客户端能提供的无非也就是HTTP操作的API) 而基于Token的身份认证就是应对这种变化而生的,它更开放,安全性也更高. 基于Token的身份认证

  • 浅谈如何在ASP.NET Core中实现一个基础的身份认证

    ASP.NET终于可以跨平台了,但是不是我们常用的ASP.NET, 而是叫一个ASP.NET Core的新平台,他可以跨Windows, Linux, OS X等平台来部署你的web应用程序,你可以理解为,这个框架就是ASP.NET的下一个版本,相对于传统ASP.NET程序,它还是有一些不同的地方的,比如很多类库在这两个平台之间是不通用的. 今天首先我们在ASP.NET Core中来实现一个基础的身份认证,既登陆功能. 前期准备: 1.推荐使用 VS 2015 Update3 作为你的IDE,下

  • C#进阶系列 WebApi身份认证解决方案推荐:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想想都恐怖.经过一番折腾,总算是加上了接口的身份认证,在此记录下,也给需要做身份认证的园友们提供参考. 一.为什么需要身份认证 在前言里面,我们说了,如果没有启用身份认证,那么任何匿名用户只要知道了我们服务的url,就能随意访问我们的服务接口,从而访问或修改数据库. 1.我们不加身份认证,匿名用户可以

  • 关于C#.net winform程序验证moss的集成身份认证实例

    最近开发vsto程序需要上传文档到moss平台,因为网站使用的是windows集成认证,所以遇到了权限问题,需要输入密码.使操作和用户体验非常不方便,研究了好久没有找到好的方法,最后终于让我踏破铁鞋总结出了下面的方法,原理我个人的理解应该是模拟IE发送验证的消息进行验证,可以通过实现登录的问题. 注:需要添加名称为Microsoft XML,V2.6以上版本的COM引用 复制代码 代码如下: private void button3_Click(object sender, EventArgs

  • asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案

    目录 认证授权 身份认证 授权 默认授权 选择授权 总结 开发了一个公司内部系统,使用asp.net core 3.1.在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据.并且只是几个简单的接口不准备再重新部署一个站点,所以就直接在MVC的项目里面加了一个API区域用来写接口.这时候因为是接口所以就不能用cookie方式进行认证,得加一个jwt认证,采用多种身份验证方案来进行认证授权. 认证授权 身份验证是确定用户身份的过程. 授权是确定用户是否有权

  • 深入解读ASP.NET Core身份认证过程实现

    长话短说:上文我们讲了 ASP.NET Core 基于声明的访问控制到底是什么鬼? 今天我们乘胜追击:聊一聊ASP.NET Core 中的身份验证. 身份验证是确定用户身份的过程. 授权是确定用户是否有权访问资源的过程. 1. 万变不离其宗 显而易见,一个常规的身份认证用例包括两部分: ① 对用户进行身份验证 ② 在未经身份验证的用户试图访问受限资源时作出反应 已注册的身份验证处理程序及其配置选项被称为"方案",方案可用作一种机制,供用户参考相关处理程序的身份验证.挑战和禁止行为. 我

  • Asp.net Core中实现自定义身份认证的示例代码

    Asp.Net Core中虽然集成了许多常用的身份认证,但很多时候,我们还是需要实现自己的身份认证接口,本文这里就简单的介绍下如何实现自定义身份认证接口. 首先写一个简单的接口. [Authorize] [HttpGet] public object Foo() { return DateTime.Now.ToString(); } 由于有Authorize标记,访问函数体前会判断用户是否通过认证,由于这里没有通过认证,会的得到一个500错误. 自定义认证处理类: 实现一个IAuthentica

  • .net使用jwt进行身份认证的流程记录

    目录 什么是身份认证和鉴权 jwt工作流程 token是如何生成的 jwt三部分 jwt是如何保证数据不会被篡改的 .net webapi 的 demo 总结 什么是身份认证和鉴权 举个例子 假设有这么一个小区,小区只允许持有通行证的人进入,陌生人如果想直接进入小区会被保安拦住,他必须先办理通行证才会被允许进入 类比身份认证和鉴权体系 一个人要访问我的一个机密的接口,我首先需要知道你是谁,搞清楚你是谁的过程就是身份认证,如果我搞不清楚你是谁,那你就是陌生人,身份认证失败. 身份认证通过,并不一定

  • Web API身份认证解决方案之Basic基础认证

    一.WebApi中为什么需要身份认证 我们在使用WebApi的时候,都是通过URL去获取数据.也就是说,任何人只要知道了URL地址,就能随意的访问后台的服务接口,就可以访问或者修改数据库数据了,这样就会导致很严重的后果. 1.我们不加身份认证,匿名用户可以直接通过url随意访问接口: 2.增加了身份认证之后,只有带了票据的请求才能访问对应的接口. 二.常见的认证方式 WebApi中常见的认证方式有如下几种: FORM身份验证 集成WINDOWS验证 Basic基础认证 Digest摘要认证 三.

  • asp.net基于JWT的web api身份验证及跨域调用实践

    随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的做法有所不同,除了面临跨域提交cookie的烦人问题外,更重要的是,有些终端可能根本不支持cookie. Json Web Token(jwt)是一种不错的身份验证及授权方案,简单的说就是调用端调用api时,附带上一个由api端颁发的token,以此来验证调用者的授权信息. 但由于时间关系,不对jw

  • 简单Web service 身份验证解决方案

    软件环境:Web服务程序部署在分布于各地的工厂服务器,这些服务器位于内网之中,没有固定外网IP,且不能通过外网进行访问.调用这些Web服务的是一台连接至internet的WEB服务器,该WEB服务器通过VPN与各个工厂的服务器相连. 解决方案一:通过SOAP Header传递用户名和密码. 1. 首先需要在服务中定义一个从 SOAPHeader 派生的类,表示传入 SOAP 标头的数据. 复制代码 代码如下: public class CredentialSoapHeader : System.

  • .Net Core 3.1 Web API基础知识详解(收藏)

    目录 一.前言 二.Swagger调试Web API 三.配置文件 四.文件上传 五.统一WebApi数据返回格式 六.模型验证 七.日志使用 八.依赖注入 九.缓存 十.异常处理 十一.应用安全与JWT认证 十二.跨域 一.前言 随着近几年前后端分离.微服务等模式的兴起,.Net Core也似有如火如荼之势 ,自16年发布第一个版本到19年底的3.1 LTS版本,以及将发布的.NET 5,.NET Core一路更迭,在部署和开发工具上也都支持了跨平台应用.一直对.Net Core有所关注,但未

  • ASP.NET第一次访问慢的完美解决方案(MVC,Web Api)

    问题现象 访问asp.net web项目的时候,第一次访问比较慢,当闲置一段时间后,再次访问还是会非常慢. 问题原因 这是IIS回收造成的,再次访问的时候会初始化操作,初始化需要耗费时间,所以访问会比较慢,第二次访问的时候不需要初始化操作,因此变快了. 解决办法 IIS应用初始化会在网站第一次创建后或者对应网站的应用程序池回收后,自动开启新程序池,并启动网站初始化,模拟一次正常请求,使网站一直处于在线状态. 修改IIS中的配置 1.修改启用应用程序池(AlwaysRunning):保证应用程序池

  • 详解基于Android App 安全登录认证解决方案

    近几年移动互联网的高速发展,智能手机的使用用户呈现爆炸性增长,手机终端上的App 种类繁多,大多数App 都需要与后台系统进行交互,交互的第一步需要进行登录认证,过于简单的认证方式可能被破解从而造成用户信息的泄露甚至威胁着用户的财产安全.为此基于Android 系统,对比现有几种常见的App 登录认证方式,并提出一种采用RSA 非对称加密和加入Token 时效机制的登录认证解决方案.在登录验证阶段采用RSA 非对称加密方式,App 端对服务器端返回的Token 信息加上时间戳,将处理后的Toke

  • 创建一个完整的ASP.NET Web API项目

    Visual Studio为我们提供了专门用于创建ASP.NET Web API应用的项目模板,借助于此项目模板提供的向导,我们可以"一键式"创建一个完整的ASP.NET Web API项目.在项目创建过程中,Visual Studio会自动为我们添加必要的程序集引用和配置,甚至会为我们自动生成相关的代码,总之一句话:这种通过向导生成的项目在被创建之后其本身就是一个可执行的应用. 一.通过VS2013..NET 4.5.1创建一个Web API项目 1.解决方案下面新建项目 2.选择项

  • ASP.NET Web API教程 创建Admin控制器实例分享

    In this section, we'll add a Web API controller that supports CRUD (create, read, update, and delete) operations on products. The controller will use Entity Framework to communicate with the database layer. Only administrators will be able to use thi

  • ASP.NET Web API教程 创建Admin视图详细介绍

    Now we'll turn to the client side, and add a page that can consume data from the Admin controller. The page will allow users to create, edit, or delete products, by sending AJAX requests to the controller. 现在我们转入客户端,并添加一个能够使用从Admin控制器而来的数据的页面.通过给控制器发

随机推荐