`
sillycat
  • 浏览: 2542874 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Spray(8)REST API Project - Auth

 
阅读更多
Spray(8)REST API Project - Auth
6. How to Deal with Auth
My structure for this will be as follow:
/**
* 1 User(1, 'admin', ... , 'admin')
* 2 User(2, 'manager', ..., 'manager')
* 3 User(3, 'customer', ..., 'customer')
*/
caseclass User(id: Option[Long], userName: String, age: Int, userType: UserType.Value, createDate: DateTime, expirationDate: DateTime, password: String)

/**
* 1 Role(1, "admin", "")
* 2 Role(2, "manager", "")
* 3 Role(3, "customer", "")
*/
caseclass Role(id: Option[Long], roleCode: String, description: String)

/**
* 1. RUserRole(1, 1)
* 2. RUserRole(2, 2)
* 3. RUserRole(3, 3)
*/

caseclass RUserRole(roleId : Long, userId : Long)

Since we use basicHttpAuthority, the most important part is to get the data from the header
  def getToken(ctx: RequestContext): Option[UserPass] = {
    valauthHeader = ctx.request.headers.findByType[Authorization]
    valcredentials = authHeader.map { case Authorization(creds) => creds }
    credentials.flatMap {
      case BasicHttpCredentials(user, pass) => Some(UserPass(user, pass))
      case _ => None
    }

  }

Mock the user data for now
def auth(userName: String, password: String)(implicit session: Session) : Option[User] = {
      (userName, password) match {
        case ("admin","admin") => Option(User(Some(1), "admin", 100, UserType.ADMIN, new DateTime(), new DateTime(),"admin"))
        case ("customer","customer") => Option(User(Some(2), "customer", 100, UserType.CUSTOMER, new DateTime(), new DateTime(),"customer"))
        case ("manager","manager") => Option(User(Some(3), "manager", 100, UserType.SELLER, new DateTime(), new DateTime(),"manager"))
        case _ => None
      }

}

When we use that, it will be like this
trait URLRouterService extends HttpService with UsersAuthenticationDirectives {
authenticate(adminOnly) { user =>
…snip…
authenticate(customerOnly) { user =>
…snip...
authenticate(withRole("manager")) { user =>

The test specification class for this auth thing will be look like this>
package com.sillycat.easysprayrestserver.actor

import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.http._
import StatusCodes._
import spray.http.BasicHttpCredentials
import spray.http.HttpHeaders.Authorization
import spray.routing.AuthenticationFailedRejection
import spray.routing.AuthenticationRequiredRejection
import spray.routing.HttpService
import spray.routing.RequestContext
import spray.routing.authentication.Authentication
import spray.routing.authentication.UserPass
import spray.util.executionContextFromActorRefFactory
import spray.util.pimpSeq

class URLRouterActorSpec extends Specification with Specs2RouteTest with URLRouterService {

  def actorRefFactory = system

  "The URLRouterActor" should {

    "Anyone can visit this page." in {
      Get("/v1/sillycat/resource/all") ~> route ~> check { entityAs[String] must contain("Morning") }
    }

    "Admin can visit this page." in {
      Get("/v1/sillycat/resource/admin-only") ~> addCredentials(BasicHttpCredentials("admin", "admin")) ~> route ~> check { entityAs[String] must contain("Morning") }
    }

    "No UserName Password can not visit this page." in {
      Get("/v1/sillycat/resource/admin-only") ~> route ~> check {
      rejection === AuthenticationRequiredRejection("https", "sillycat")
      }
    }
   
    "Wrong UserName Password can not visit this page." in {
      Get("/v1/sillycat/resource/admin-only") ~> addCredentials(BasicHttpCredentials("admin", "asdfadsf")) ~> route ~> check {
      rejection === AuthenticationFailedRejection("sillycat")
      }
    }

  }


}

7. How to Work with Logback
come soon…

8. How to work with DB
come soon...


9. How to Work with Actor
come soon…


10. How to do Validation
come soon...



Tips:
1. Log Error
Error Message:
app[ERROR]: May 1, 2013 1:57:26 PM com.mchange.v2.log.MLog <clinit>
app[ERROR]: INFO: MLog clients using java 1.4+ standard logging.
app[ERROR]: May 1, 2013 1:57:27 PM com.mchange.v2.c3p0.C3P0Registry banner
app[ERROR]: INFO: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]

Solution:

2. JRebel
The purpose for this is to enable hot reloading.
Follow the document here https://github.com/spray/sbt-revolver
Visit this website to get a free license https://my.jrebel.com/plans/

We can see the information here https://my.jrebel.com/account/my-dashboard

And get the license from here https://my.jrebel.com/account/how-to-activate
  
Download the latest package named rebel-5.2.2-nosetup.zip

Unzip this file and place in the directory /Users/carl/tool/jrebel
Link it to the working directory
>sudo ln -s /Users/carl/tool/jrebel /opt/jrebel

Run the active command
>cd /opt/jrebel/bin
>./jrebel-config.sh

After that, make sbt-revoler find that plugin
>vi ~/.profile
export JREBEL_PATH=/opt/jrebel/jrebel.jar
>. ~/.profile

That is it. We do not need to re-start our spray server now.

References:
http://www.gtan.com/akka_doc/scala/routing.html
https://github.com/cakesolutions/spray-auth-example
http://spray.io/documentation/spray-routing/
https://github.com/spray/spray/wiki/Authentication-Authorization
https://github.com/spray/spray/wiki/Configuration
https://github.com/spray/spray/wiki

https://github.com/spray/sbt-revolver

https://github.com/spray/spray/blob/master/spray-routing-tests/src/test/scala/spray/routing/SecurityDirectivesSpec.scala

http://doc.akka.io/docs/akka/2.1.0/scala/logging.html
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics