热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一、设置浏览器客户端

一、设置浏览器客户端如果你在读这本书,那是因为你理解保护你的webAPI的重要性。ASP

一、设置浏览器客户端

如果你在读这本书,那是因为你理解保护你的 web API 的重要性。 ASP.NET Web API 是一个框架,它帮助构建可以被广泛的客户端利用的 HTTP 服务。 所以确保 Web API 的安全是非常重要的。

ASP.NET Web API 1.0 没有任何安全特性,所以安全是由主机(如 Internet Information Server)提供的。 在 ASP.NET Web API 2,安全特性如 Katana 被引入。 为了保护 Web API,让我们了解所涉及的各种技术,并选择正确的方法。

在本章中,我们将涵盖以下主题:


  • ASP.NET Web API 安全体系结构

  • 设置浏览器客户端

  • 认证和授权

  • 在 HTTP 消息处理程序中实现认证

  • 设置主

  • 使用[Authorize]属性

  • 自定义授权过滤器

  • 控制器操作中的授权


NET Web API 安全体系结构

本节将向您概述 Web API 安全体系结构,并向您展示可用于安全相关事务的所有各种扩展点。 ASP.NET Web API 安全体系结构由三个主要层组成。 宿主层充当 Web API 和网络堆栈之间的接口。 消息处理程序管道层支持实现诸如认证和缓存等横切关注点。 控制器处理层是执行控制器和操作、绑定和验证参数以及创建 HTTP 响应消息的地方。 该层还包含一个过滤器管道,如下图所示:

ASP.NET Web API security architecture

图 1 -此图像显示了保护 Web API 所涉及的组件

让我们简要讨论一下 Web API 管道中每个组件的用途,如下所示:


  • Open Web Interface for . net(OWIN)是新的开放标准托管基础设施。 微软已经在 OWIN 和的基础上构建了自己的框架 Katana,所有的 Web API 安全技术,如认证方法(例如,基于令牌的认证)和对社交登录提供商(例如,谷歌和 Facebook)的支持都将在 OWIN 层实现。

  • 消息处理程序是一个类,用于接收 HTTP 请求并返回 HTTP 响应。 不建议在消息处理程序级别实现认证。 消息处理器用于跨源资源共享(CORS)。

  • 认证过滤器保证在授权过滤器之前运行。 如果您对在 OWIN 层操作认证逻辑不感兴趣,您可以直接转移到控制器或操作。 认证过滤器对于调用基于 owen 的认证逻辑非常有用。

  • 授权过滤器是管道中的位置,您可以在实际昂贵的业务逻辑在模型绑定和验证中运行以及控制器动作被调用之前重新检查请求。

现在我们已经熟悉了安全体系结构,接下来我们将设置客户机。

设置浏览器客户端

让我们创建一个用于联系人查找的 Web API。 这个联系人查找 Web API 服务将向调用的客户端应用返回联系人列表。 然后,我们将使用 jQuery AJAX 调用来列出和搜索联系人,使用 Contact Lookup 服务。

这个应用将帮助我们在本书中演示 Web API 安全性。

实现 Web API 查找服务

在这个节中,我们将创建一个联系人查找 web API 服务,该服务返回一个联系人列表,该列表采用Javascript 对象标记(JSON)格式。 使用这个联系人查找的客户端是一个简单的 web 页面,它使用 jQuery 显示联系人列表。 按照以下步骤启动项目:


  1. 在 Visual Studio 的Start页面中创建新项目

  2. 选择 Visual c# Installed Template 命名为Web

  3. 选择ASP.NET Web 应用

  4. Name the project ContactLookup and click OK, as shown in the following screenshot:

    Implementing Web API lookup service

    图 2 -我们已经命名了 ASP.NET Web 应用“ContactLookup”


  5. 新 ASP. net 中选择模板。 对话框。


  6. Check Web API and click OK under Add folders and core references, as shown in the following:

    Implementing Web API lookup service

    图 3 -我们选择空 Web API 模板


我们只是创建了一个空的 Web API 项目。 现在让我们添加所需的模型。

添加模型

让我们从开始,通过以下步骤的帮助创建一个代表联系人的简单模型:


  1. First, define a simple contact model by adding a class file to the Models folder.

    Adding a model

    图 4 -右键单击 Models 文件夹并添加一个 Model 类


  2. 命名类文件Contact 并声明Contact类的属性。

    namespace ContactLookup.Models
    {
    public class Contact
    {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Mobile { get; set; }
    }
    }


我们刚刚添加了一个名为Contact的模型。 现在让我们添加所需的 web API 控制器。

添加控制器

HTTP 请求是由 Web API 中的控制器对象处理的。 让我们定义一个带有两个动作方法的控制器。 一个操作返回联系人列表,另一个操作返回特定于给定 ID 的单个联系人:


  1. Add the Controller under the Controllers folder in Solution Explorer.

    Adding a controller

    图 5 -右键单击 Controllers 文件夹并添加控制器


  2. Select Web API Controller – Empty and click on Add in the Add Scaffold dialog.

    Adding a controller

    图 6 -选择一个空的 Web API 控制器


  3. Let's name the controller ContactsController in the Add Controller dialog box and click Add.

    Adding a controller

    图 7 -命名控制器

    这将在Controllers文件夹中创建ContactsController.cs文件,如下图所示:

    Adding a controller

    图 8 -应用中的 Controllers 文件夹中添加了 ContactsController


  4. 用以下代码替换ContactsController中的代码:

    ```
    namespace ContactLookup.Controllers
    {
    public class ContactsController : ApiController
    {
    Contact[] cOntacts= new Contact[]
    {
    new Contact { Id = 1, Name = "Steve", Email = "steve@gmail.com", Mobile = "+1(234)35434" },
    new Contact { Id = 2, Name = "Matt", Email = "matt@gmail.com", Mobile = "+1(234)5654" },
    new Contact { Id = 3, Name = "Mark", Email = "mark@gmail.com", Mobile = "+1(234)56789" }
    };

    public IEnumerable<Contact> GetAllContacts()
    {
    return contacts;
    }
    public IHttpActionResult GetContact(int id)
    {
    var contact = contacts.FirstOrDefault(x => x.Id == id);
    if (contact == null)
    {
    return NotFound();
    }
    return Ok(contact);
    }
    }

    }
    ```


为简单起见,联系人存储在控制器类中的固定数组中。 控制器定义为,有两个动作方法。 联系人列表将由GetAllContacts方法以 JSON 格式返回,GetContact方法根据其 ID 返回单个联系人。 一个惟一的 URI 应用于控制器上的每个方法,如下表所示:

|

控制器方法

|

尤里

|
| --- | --- |
| GetAllContacts | /api/contacts |
| GetContact | /api/contacts/id |

使用 Javascript 和 jQuery 使用 Web API

在这个节中,为了演示使用或不使用任何安全机制调用 web API,让我们创建一个 HTML 页面,使用 web API 并使用 jQuery AJAX 调用的结果更新页面:


  1. In the Solution Explorer pane, right-click on the project and add New Item.

    Consuming the Web API using Javascript and jQuery

    图 9 -从解决方案资源管理器的上下文菜单中选择 add new item


  2. Create HTML Page named index.html using the Add New Item dialog.

    Consuming the Web API using Javascript and jQuery

    图 10 -添加索引 html 文件通过选择 html 页面在添加新项目对话框


  3. 用以下代码替换index.html文件中的内容:

    ```

    Contact Lookup

    All Contacts





      Search by ID

      var uri = 'api/contacts';

      $(document).ready(function () {
      // Send an AJAX request
      $.getJSON(uri)
      .done(function (data) {
      // On success, &#39;data&#39; contains a list of contacts.
      $.each(data, function (key, contact) {
      // Add a list item for the contact.
      $(&#39;

    • &#39;, { text: formatItem(contact) }).appendTo($(&#39;#contacts&#39;));
      });
      });
      });

    function formatItem(contact) {
    return contact.Name + ', email: ' + contact.Email + ', mobile: ' + contact.Mobile;
    }

    function search() {
    var id = $(&#39;#contactId&#39;).val();
    $.getJSON(uri + &#39;/&#39; + id)
    .done(function (data) {
    $(&#39;#contact&#39;).text(formatItem(data));
    })
    .fail(function (jqXHR, textStatus, err) {
    $(&#39;#contact&#39;).text(&#39;Error: &#39; + err);
    });
    }


    ```



    获取联系人列表

    我们需要向/api/contacts 发送一个 HTTP GET 请求来获取联系人列表。 AJAX 请求由 jQuerygetJSON函数发送,并在响应中接收 JSON 对象数组。 如果请求成功,将调用done函数中的回调函数。 在回调中,我们用联系信息更新 DOM,如下所示:

    $(document).ready(function () {
    // Send an AJAX request
    $.getJSON(uri)
    .done(function (data) {
    // On success, 'data' variable contains a list of contacts.
    $.each(data, function (key, contact) {
    // Add a list item for the contact.
    $('

  4. ', { text: formatItem(contact) }).appendTo($('#contacts'));
    });
    });
    });

  5. 通过 ID 获取联系人

    要通过 ID 获取联系人,向/api/contacts/id发送一个 HTTP get 请求,其中id是联系人 ID。

    function search() {
    var id = $('#contactId').val();
    $.getJSON(uri + '/' + id)
    .done(function (data) {
    $('#contact').text(formatItem(data));
    })
    .fail(function (jqXHR, textStatus, err) {
    $('#contact').text('Error: ' + err);
    });
    }

    getJSON中的请求 URL 有联系人 ID。 响应是此请求的单个联系人的 JSON 表示。

    运行应用

    F5启动调试应用。 输入联系人 ID,点击搜索:

    Running the application

    图 11 -样例基于浏览器的客户端应用的用户界面

    认证授权

    我们创建了一个简单的 web API,它根据 ID 返回联系人列表或特定的联系人。 任何支持 HTTP 的客户端都可以访问这个 web API,但安全性还不够。 在认证和授权机制的帮助下,我们可以保护这个 web API 免受未经授权的访问。


    认证

    认证是在主机Internet Information Service(IIS)中对 web API 进行认证。 Internet 信息服务使用 HTTP 模块进行认证。 我们还可以用自己的 HTTP 模块实现自定义认证。

    主机在对用户进行认证时创建主体。 Principal 是一个IPrincipal对象,它表示运行代码的安全上下文。 您可以从主机连接的Thread.CurrentPrincipal中访问当前的主体。 可以从 principal 的Identity对象访问用户信息。 如果用户通过认证,Identity.IsAuthenticated属性返回true。 如果用户没有被验证,Identity.IsAuthenticated将返回false

    授权

    授权在向控制器提供成功的认证之后发生。 当做出更细粒度的选择时,它帮助您授予对资源的访问权。

    对于任何未经授权的请求,授权筛选器将返回一个错误响应,并且不允许执行该操作。 这是因为授权过滤器将在控制器操作中的任何语句之前首先执行。

    实现 HTTP 消息处理程序中的认证

    对于一个自托管 web API,最佳的实践是在HTTP 消息处理程序中实现认证。 主体将在验证 HTTP 请求后由消息处理程序设置。 对于自托管的 web API,可以考虑在消息处理程序中实现认证。 否则,请使用 HTTP 模块。

    下面的代码片段展示了一个在 HTTP 模块中实现的基本认证示例:

    public class AuthenticationHandler : DelegatingHandler
    {
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
    CancellationToken cancellationToken)
    {
    var credentials = ParseAuthorizationHeader(request);
    if (credentials != null)
    {
    // Check if the username and passowrd in credentials are valid against the ASP.NET membership.
    // If valid, the set the current principal in the request context
    var identity = new GenericIdentity(credentials.Username);
    Thread.CurrentPrincipal = new GenericPrincipal(identity, null);;
    }
    return base.SendAsync(request, cancellationToken)
    .ContinueWith(task =>
    {
    var response = task.Result;
    if (credentials == null && response.StatusCode == HttpStatusCode.Unauthorized)
    Challenge(request, response);
    return response;
    });
    }
    protected virtual Credentials ParseAuthorizationHeader(HttpRequestMessage request)
    {
    string authorizationHeader = null;
    var authorization = request.Headers.Authorization;
    if (authorization != null && authorization.Scheme == "Basic")
    authorizationHeader = authorization.Parameter;
    if (string.IsNullOrEmpty(authorizationHeader))
    return null;
    authorizationHeader = Encoding.Default.GetString(Convert.FromBase64String(authorizationHeader));
    var authenticationTokens = authorizationHeader.Split(':');
    if (authenticationTokens.Length < 2)
    return null;
    return new Credentials() { Username = authenticationTokens[0], Password = authenticationTokens[1], };
    }
    void Challenge(HttpRequestMessage request, HttpResponseMessage response)
    {
    response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", request.RequestUri.DnsSafeHost));
    }
    public class Credentials
    {
    public string Username { get; set; }
    public string Password { get; set; }
    }
    }


    设置主体

    如果应用实现了自定义认证逻辑,那么我们必须在两个地方设置主体:

    下面的代码显示了如何设置主体:

    private void SetPrincipal(IPrincipal principal)
    {
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
    {
    HttpContext.Current.User = principal;
    }
    }


    使用[Authorize]属性

    AuthorizeAttribute将确保用户是通过验证还是未通过验证。 如果用户未通过认证,且不调用相应的操作,则返回 HTTP 状态码为 401 的未授权错误。 Web API 允许您以三种方式应用筛选器。 我们可以在全局级别、控制器级别或单个操作级别应用它们。

    全局授权过滤器

    为了对所有 Web API 控制器应用授权过滤器,我们需要将AuthorizeAttribute过滤器添加到Global.asax文件的全局过滤器列表中,如下所示:

    public static void Register(HttpConfiguration config)
    {
    config.Filters.Add(new AuthorizeAttribute());
    }


    控制器级授权过滤器

    要为特定的控制器应用授权过滤器,我们需要用 filter 属性装饰控制器,如下代码所示:

    // Require authorization for all actions on the controller.
    [Authorize]
    public class ContactsController : ApiController
    {
    public IEnumerable<Contact> GetAllContacts() { ... }
    public IHttpActionResult GetContact(int id) { ... }
    }


    动作级别授权过滤器

    要对特定的动作应用授权过滤器,我们需要将属性添加到 action 方法中,如下代码所示:

    public class ContactsController : ApiController
    {
    public IEnumerable<Contact> GetAllContacts() { ... }
    // Require authorization for a specific action.
    [Authorize]
    public IHttpActionResult GetContact(int id) { ... }
    }


    自定义授权过滤器

    要实现自定义授权筛选器,我们需要创建派生AuthorizeAttributeAuthorizationFilterAttributeIAuthorizationFilter的类。


    控制器动作中的授权

    有时,可能需要在基于主体处理请求后更改行为。 在这种情况下,我们可以在控制器操作中实现授权。 例如,如果您想根据用户的角色操作响应,我们可以通过动作方法本身的ApiController.User属性验证登录的用户角色:

    public HttpResponseMessage Get()
    {
    if (!User.IsInRole("Admin"))
    {
    // manipulate the response to eliminate information that shouldn't be shared with non admin users
    }
    }


    总结

    这很容易,不是吗? 我们刚为 APS 设置了安全系统.NET Web API,我们将在接下来的章节中构建它。

    您学习了 ASP 的安全体系结构.NET Web API,它提供了一个整体的视图。 然后我们设置浏览器客户机,从实现 Web 查找服务到使用 Javascript 和 jQuery 代码调用 Web API。

    您还学习了认证和授权技术,我们将在本书后面详细介绍这些技术。 接下来,您了解了 HTTP 消息处理程序、Principal 和用于控制用户授权的[Authorize]属性。

    最后,您了解了自定义授权和控制器操作中的授权,以便在基于主体处理请求后更改行为。

    你在这一章学到了很多东西。 然而,这仅仅是个开始。 在下一章中,您将实现 Web API 的安全套接字层。 让我们开始吧!


    推荐阅读
    • Web开发框架概览:Java与JavaScript技术及框架综述
      Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
    • javascript分页类支持页码格式
      前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
    • 解决Bootstrap DataTable Ajax请求重复问题
      在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
    • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
    • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
      技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
    • 深入探索HTTP协议的学习与实践
      在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
    • 本文探讨了使用JavaScript在不同页面间传递参数的技术方法。具体而言,从a.html页面跳转至b.html时,如何携带参数并使b.html替代当前页面显示,而非新开窗口。文中详细介绍了实现这一功能的代码及注释,帮助开发者更好地理解和应用该技术。 ... [详细]
    • 本文详细介绍了如何在 Linux 系统上安装 JDK 1.8、MySQL 和 Redis,并提供了相应的环境配置和验证步骤。 ... [详细]
    • 使用ArcGIS for Java和Flex浏览自定义ArcGIS Server 9.3地图
      本文介绍了如何在Flex应用程序中实现浏览自定义ArcGIS Server 9.3发布的地图。这是一个基本的入门示例,适用于初学者。 ... [详细]
    • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
    • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
    • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
      本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
    • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
      在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
    • 基于试题数据的智能化管理平台采用Java语言进行面向对象编程,旨在构建一个高效的试题信息管理系统。该系统在JDK 6.0和MyEclipse 10.6环境下开发,通过优化试题数据管理和处理流程,提升系统的稳定性和用户体验。平台支持多用户操作,具备强大的数据处理能力和灵活的扩展性,适用于各类教育机构和考试组织。 ... [详细]
    • 为开发者提供了一系列实用的参考网站和资源链接,包括HTML速查手册( 和 ),帮助开发者快速查找和学习相关技术知识。此外,还涵盖了其他重要的开发工具和文档,为编程工作提供全面支持。 ... [详细]
    author-avatar
    tuigone
    这个家伙很懒,什么也没留下!
    Tags | 热门标签
    RankList | 热门文章
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有