Spray中的Authentication和JMeter测试

Spray Authentication

在Spray中,如果需要对REST API添加认证,可以使用Spray提供的Authenticate功能。本质上,Authenticate属于安全指令(Security Directive)提供的功能。它的接口定义本质上为:

def authenticate[T](auth: => Future[Authentication[T]])(implicit executor: ExecutionContext): Directive1[T]

def authenticate[T](auth: ContextAuthenticator[T])(implicit executor: ExecutionContext): Directive1[T]

Spray使用了Magnet Pattern,使其可以编写出更符合DSL风格的API。所以我们看到的authenticate()方法的实现实际为:

trait SecurityDirectives extends scala.AnyRef {
  def authenticate[T](magnet : spray.routing.directives.AuthMagnet[T]) : spray.routing.Directive1[T] = ???
}

正是因为运用了Magnet Pattern,我们可以直接在Path中通过authenticate添加认证功能,例如:

def myUserPassAuthenticator(userPass: Option[UserPass]): Future[Option[String]] =
    Future {
      if (userPass.exists(up => up.user == "John" && up.pass == "p4ssw0rd")) Some("John")
      else None
    }
  val customerRoute =
    path("customers") {
      authenticate(BasicAuth(myUserPassAuthenticator _, realm = "admin area")) {  user =>
        get {
          handleRequest {
            AllCustomers
          }
        } ~ post {
          entity(as[Customer]) {
            customer =>
              handleRequest {
                CreateCustomer(customer.email, customer.name)
              }
          }
        }
      }
    }

Spray Authentication通过BasicHttpAuthenticator类来支持Basic Access Authentication。上面代码片段中的BasicAuth是一个对象,提供了多个构造函数重载。这段代码中传递了两个参数:第一个参数为UserPassAuthenticator类型;第二个参数用于指定认证的realm。

UserPassAuthenticator是一个type,实质为一个函数:

type UserPassAuthenticator[T] = Option[UserPass] => Future[Option[T]]

上面代码中的myUserPassAuthenticator就是自定义的一个UserPassAuthenticator。显然,BasicAuth接收一个函数作为参数,使得我们可以更容易自定义。若要通过认证,我们可以创建BasicHttpCredentials对象,将其加入到authorization header中。Spray也支持配置的形式管理用户信息,具体内容可参见Spray的官方文档Authentication。

JMeter测试

我用JMeter来测试这个具有Authentication的REST API。由于具有认证功能,因而,在JMeter中需要添加Http Authorization Manager。Http Authorization Manager是Config Element,添加后,需要配置认证信息,包括Base URL、Username、Password、Realm等。如下图所示:

注意,在配置Base URL时,应该设置为完整的URL(当然,也可以使用JMeter的变量)。

如果为了验证执行是否成功,建议添加View Result Tree这个Listener,因为它给出的结果信息中包括了Sampler result、Request与Response Data等信息,这样有利于我们甄别测试的Http Request是否正确,如果错误,是什么原因导致的。

原文发布于微信公众号 - 逸言(YiYan_OneWord)

原文发表时间:2015-02-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

利用 Microsoft StreamInsight 控制较大数据流

原文地址:http://msdn.microsoft.com/zh-cn/magazine/hh205648.aspx 下载代码示例 生产线的产量下降后,将...

1766
来自专栏大数据钻研

前端面试那些坑

HTML Doctype作用?严格模式与混杂模式如何区分?它们有何意义? HTML5 为什么只需要写 ? 行内元素有哪些?块级元素有哪些? 空(void)元素有...

3126
来自专栏狮乐园

【译】Understanding SOLID Principles - Dependency Inversion

当我们在读书,或者在和一些别的开发者聊天的时候,可能会谈及或者听到术语SOILD。在这些讨论中,一些人会提及它的重要性,以及一个理想中的系统,应当包含它所包含的...

723
来自专栏JackieZheng

AngularJS in Action读书笔记2——view和controller的那些事儿

今天我们来818《angularjs in action》的第三章controller和view。 1.Big Picture概览图 ? image.png...

18710
来自专栏Android相关

X86处理器架构--Nehalem

最开始的处理器比较简单,8086处理器是评估当前的指令指针(CS:IP)指向的指令,然后再执行解码、执行、退出,并移动指令指针到下一个位置,每一个新的芯片都做了...

1004
来自专栏葡萄城控件技术团队

对《30个提高Web程序执行效率的好经验》的理解

阅读了IT文章《30个提高Web程序执行效率的好经验》,这30条准则对我们web开发是非常有用的,不过大家可能对其中的一些准则是知其然而不知其所以然。 下面是我...

1695
来自专栏腾讯Bugly的专栏

Android UI:机智的远程动态更新策略

1 问题描述 做过Android开发的人都遇到过这样的问题:随着需求的变化,某些入口界面通常会出现 UI的增加、减少、内容变化、以及跳转界面发生变化等问题。每次...

3349
来自专栏web前端教室

如何用JS写一个table组件 | 作业讲解

这个题目是作业区里的一道题,大家都完成的很好。论坛里的wenacy虽然没有成功的完成此作业,但这种努力的尝试才是最有价值的。 以下的内容是我个人的主观理解,偏见...

2015
来自专栏java一日一条

有经验的Java开发者和架构师容易犯的10个错误(上)

首先允许我们问一个严肃的问题?为什么Java初学者能够方便的从网上找到相对应的开发建议呢?每当我去网上搜索想要的建议的时候,我总是能发现一 大堆是关于基本入门的...

532
来自专栏更流畅、简洁的软件开发方式

【开源】QuickPager ASP.NET2.0分页控件V2.0.0.1——分页控件的源码(一) 主体

namespace JYK.Controls {     /**//// <summary>     /// 分页控件     /// PageGetData....

1677

扫码关注云+社区