Spray(14)Simple/Free/Complex Auth
We can have different auth in our spray framework.
Only Simple and Complex Auth need to have implementation class based on that.
In the AuthDirectives class, we need these kind of codes.
def localpointSimpleAuth = authenticate(new BrandUserSimpleSigAuthenticator(authDirectory)) & pathPrefix(Version) &optionalHeaderValueByName("Origin")
def localpointAuth = authenticate(new BrandUserSignatureAuthenticator(authDirectory)) & pathPrefix(Version) & optionalHeaderValueByName("Origin")
In the implementation, we usually just get some info from header and validate based on that.
package com.sillycat.localpoint.auth
import com.sillycat.localpoint.model.BrandUser
import org.joda.time.DateTime
import scala.concurrent.{ Future, ExecutionContext }
import spray.routing.authentication._
import com.sillycat.localpoint.auth.model._
import com.sillycat.localpointauth.directory.AuthDirectory
import com.sillycat.localpoint.auth.util.BrandCodeExtractor
import spray.http._
import spray.http.HttpHeaders.Authorization
import spray.util.pimpSeq
import com.typesafe.scalalogging.slf4j.Logging
import spray.routing.AuthenticationFailedRejection
import spray.routing.RequestContext
import scala.Some
import spray.routing.AuthenticationFailedRejection
import spray.routing.RequestContext
import scala.Some
import spray.routing.directives.{ RouteDirectives, MiscDirectives, BasicDirectives, MarshallingDirectives }
import spray.routing.directives.BasicDirectives._
import spray.routing.AuthenticationFailedRejection
import spray.routing.RequestContext
import scala.Some
import shapeless.{ HNil, :: }
import shapeless._
import spray.httpx.marshalling._
import spray.httpx.unmarshalling._
import spray.http._
class BrandUserSimpleSigAuthenticator(authDirectory: AuthDirectory)(implicit val executionContext: ExecutionContext) extends ContextAuthenticator[BrandUserWithPrivileges]
with Logging {
def apply(ctx: RequestContext) = {
val authRequestOption = getAuthRequest(ctx)
BrandCodeExtractor(ctx.request.uri.authority.host.address) match {
case Some(b) => {
authRequestOption match {
case Some(x) => {
checkSimpleSig(x, b)
}
case _ => {
logger.warn("authenticate fail, parse header fail.")
Future(Left(AuthenticationFailedRejection("Realm")))
}
}
}
case _ => {
logger.warn("authenticate fail, system can not parse the brand code from host URL.")
Future(Left(AuthenticationFailedRejection("Realm")))
}
}
}
def getAuthRequest(ctx: RequestContext): Option[String] = {
val uri = ctx.request.uri.path.toString
val authHeader = ctx.request.headers.findByType[`Authorization`]
val tokenString = authHeader match {
case Some(x) => {
logger.debug("Header is there, try get token string from header " + x)
x.value
}
case _ => {
logger.debug("Header is empty, Body is empty.")
""
}
}
Some(tokenString)
}
def checkSimpleSig(authRequest: String, brandCode: String) = {
Future {
// first load the user information to get the appId/ apisecretkey/ consolekey
authDirectory.gebBrandByCode(brandCode) match {
case Some(brand) => {
if ((QABrands.contains(brandCode)) || (brand.apiSecretKey == authRequest)) {
val privileges_set = Set("RESOURCE_" + "API", "RESOURCE_" + brandCode)
val brandUser = BrandUser(None, 1l, "", "", "", true, "", "", "", false, false, true, false, DateTime.now, 0, 0)
val user = BrandUserWithPrivileges(brandUser, brandCode, privileges_set)
Right(user)
} else {
logger.warn("authenticate fail, simple signature error, AuthRequest String=" + authRequest)
Left(AuthenticationFailedRejection("Realm"))
}
}
case _ => {
logger.warn("failed to retrieve auth info with brand '%s'".format(brandCode))
Left(AuthenticationFailedRejection("Realm"))
}
}
}
}
}
When we build the router in Spray, we will build the 3 types of auth.
package com.sillycat.localpoint.console.api
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.actorRef2Scala
import akka.io.IO
import akka.routing.FromConfig
import com.sillycat.localpoint.actors.AttributeDBImportActor
import spray.can.Http
import com.sillycat.localpoint.auth.LocalpointAuthDirectives
import com.sillycat.localpoint.auth.service.AbstractAuthService
import spray.routing.{ Directives, HttpService }
import com.typesafe.config.ConfigFactory
import com.sillycat.localpoint.model._
import com.sillycat.localpoint.auth.util.ResponseHeaderUtil
import com.sillycat.localpointauth.directory.{ MultiStoreUserRepositoryComponent, AuthDirectory }
object LocalpointBridgeAPIServer extends App {
implicit val system = ActorSystem()
val config = ConfigFactory.load()
assert(Profile.env == "environment." + config.getString("build.env"))
val serverAddress: String = config.getString("server.address")
val serverPort: Int = config.getInt("server.port")
val dal: DAL = DAL()
val handler = system.actorOf(Props[LocalpointBridgeAPIServiceActor])
system.actorOf(Props[AttributeDBImportActor].withRouter(FromConfig()), name = "AttributeDBImportRouter")
IO(Http) ! Http.Bind(handler, serverAddress, serverPort)
}
class LocalpointBridgeAPIServiceActor extends Actor with LocalpointConnector {
def actorRefFactory = context
def receive = runRoute(authSimpleRoute ~ authComplexRoute ~ authFreeRoute ~ baseOptions)
}
trait LocalpointConnector extends HttpService
with AttributeMetadataService
with CampaignService
with AttributeService
with ProfileService
with DeviceIdentifierService
with LocationService
with TagService
with LocalpointAuthDirectives
with Directives {
override implicit val dal: DAL = DAL.apply
val authDirectory = new AuthDirectory with MultiStoreUserRepositoryComponent {}
def baseOptions = {
optionalHeaderValueByName("Origin") { originHeader =>
respondWithHeaders(ResponseHeaderUtil.getCrossDomainHeaders(originHeader): _*) {
options {
complete {
"OK"
}
}
}
}
}
val authFreeRoute = {
optionalHeaderValueByName("Origin") { originHeader =>
respondWithHeaders(ResponseHeaderUtil.getCrossDomainHeaders(originHeader): _*) {
attributeAuthFreeRoutes()
}
}
}
val authSimpleRoute = {
localpointSimpleAuth { (user, version, originHeader) =>
respondWithHeaders(ResponseHeaderUtil.getCrossDomainHeaders(originHeader): _*) {
attributeAuthSimpleRoutes(user, version)
}
}
}
val authComplexRoute = {
//localpointAuth { (user, version) =>
localpointAuth { (user, version, originHeader) =>
respondWithHeaders(ResponseHeaderUtil.getCrossDomainHeaders(originHeader): _*) {
authorize(verifyPrivileges(_, user)) {
attributeMetadataRoutes(user, version) ~
attributeRoutes(user, version)
}
}
}
}
}
References:
相关推荐
15% (volume fraction) SiCp/8009Al metal matrix composites (MMCs) prepared by spray co-deposition were hot-extruded and rolled to investigate the effects of porosity and local SiCp clusters on ...
欢迎来到rest scala / spray / akka / slick / mysql示例 在研究scala / spray / akka / slick / mysql REST服务期间,我已经创建了这个项目。 它可以用来学习一些有关如何使用这些技术来创建REST服务的知识。 但是...
jit spray source code
spray template on spray can
JIT Spray技术.pdf !!!!!!!!!!!!!!!!!
spray-actor-per-request, 使用每个请求模型中的参与者的示例 Spray 应用程序 每个请求的 Spray这个项目提供了一个示例 Spray 应用程序,它使用每个请求模型中的参与者。为什么要为每个HTTP请求启动一个参与者?轻松...
活化剂-阿卡-喷雾 显示围绕 Akka 演员构建的 REST API 的基本 Akka / Spray 模板。
内容概要 For newbies 基础简介,环境搭建 SLUB 细节和特性 讨论内核 Heap Spray 两个实例 几种 spray 的实际应用
微服务原型 A 具有 Scala、Akka、Spray 和 Camel/ActiveMQ 的微服务原型。 基于 Typesafe Activator 模板。 项目包含: 使用示例 actor 轻松测试 Akka 系统具有完整 CORS 支持的基于喷雾的 RESTful API Actor 和 API...
The effect of Sb spray time on the structure of InAs/GaAs quantum dot (QD) systems with Sb spray prior to the capping of a GaAs layer was determined by a Raman scattering study. The Raman spectra of ...
事实证明,Spray-SPA 对我来说是一个很好的起点。 这是我决定使用 Spray 时最完整的示例之一。 但是,我觉得该项目设计更好的版本可以为人们提供更好的参考。 我几乎重写了整个后端,使项目的结构和设计进一步从简单...
Spray-assisted assembled spherical boron nitride as fillers
spray and wait 是一种路由算法,适用于模拟仿真技术。
它最初只支持 Web 服务,并使用 Spray 来处理 HTTP 请求/响应。 Spray Http 客户端/服务层建立在 akka IO 之上。 任何其他协议,例如 ftp、jms 或 zeromq,都将在 Akka IO 之上实现。 Akka IO 已经支持 tcp 和 udp...
Writing JIT-Spray Shellcode for fun and profit
spray系统业界对比
spray-socketio 是 spray 的扩展,实现对 Socket.io 的支持。 标签:spray
PIPENET TM Spray/Sprinkler Module 是 专门针对消防系统设计而开发的专业软件, 可选用的消防规范包括NFPA 和FOC 。它 可满足诸如石油、化工、钻井平台、电站 及船只等行业对消防系统的严格且特殊的 设计要求。
该项目通过文档为您自己的Spray REST api提供了一个起点。 已实现以下REST端点: 木星 火星 宠物 为每个端点宠物,火星,木星创建一个演员。 请按照以下步骤开始: git克隆这个仓库。 $ git clone git://github...
#Spray Skeleton项目此项目是一个用于将Spray.io与MongoDB结合使用以创建REST服务的“参考”项目。 它使用zipfworks / Sprongo库作为MongoDB驱动程序。 ##入门 先决条件: Scala2.11.x sbt 0.13.x mongodb ...