2017-03-08 28 views
2

我有一个angular2客户端连接到由Play Framework实现的web api。客户端被重定向到keycloak服务器以获取令牌。我在他们的github项目中跟踪了Keycloak样本,客户端正在工作并获得令牌。不幸的是,我找不到适用于Play Framework的适配器。到目前为止,我有以下代码来检查用户是否有权访问请求的资源。Keycloak资源没有适配器的授权

val authzClient = AuthzClient.create() 

    val request = new EntitlementRequest 
    val permissions = new PermissionRequest 
    permissions.setResourceSetName(resourceName) 
    request.addPermission(permissions) 

    val entitlementResponse = authzClient.entitlement(token) 
    .get(resourceServer, request) 

我假设服务器是否返回禁止的代码,令牌用户无权访问资源。我在正确的轨道上吗?谢谢。

更新:

我开发了一个自定义操作,检查头和验证授权托克:

import pdi.jwt.{JwtAlgorithm, JwtJson} 
import play.api.libs.json.{JsValue, Json} 
import play.api.mvc.{ActionRefiner, Request, Result, Results} 

import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.util.{Failure, Success} 

case class UserRequest[A](user: User, request: Request[A]) 

object UserAction extends ActionRefiner[Request, UserRequest] { 

    private val secret = "xxxxxx" 
    private val algorithm = JwtAlgorithm.RS256 

    override protected def refine[A](request: Request[A]): Future[Either[Result, UserRequest[A]]] = Future { 
    request.headers.get("Authorization") match { 
     case Some(headerToken) => { 
     val token = headerToken.substring(7) 

     JwtJson.decode(token, secret, Seq(algorithm)) match { 
      case Success(validToken) => { 
      val tokenJson = Json.parse(validToken.content) 
      val user = extractUser(tokenJson) 
      Right(UserRequest(user, request)) 
      } 
      case Failure(ex) => 
      Left(Results.Unauthorized) 
     } 
     } 
     case None => Left(Results.Unauthorized) 
    } 
    } 

    private def extractUser(token: JsValue): User = { 
    val username = (token \ "preferred_username").as[String] 
    val firstName = (token \ "given_name").asOpt[String] 
    val familyName = (token \ "family_name").asOpt[String] 
    val name = (token \ "name").asOpt[String] 

    User(username, firstName, familyName, name) 
    } 
} 
+0

您是否找到了缺少Play Framework适配器的解决方案? – Atropo

+0

我最终使用jwt-play来验证播放服务器端的令牌。如果有帮助,我可以发布代码。 –

+0

是的,这将是有益的,谢谢! – Atropo

回答

0

是。我已经使用授权API和范围实施了具有此类检查的测试keycloak-nodejs-example项目。如果用户未通过检查权限,Keycloak将返回HTTP code 403 FORBIDDEN

https://github.com/v-ladynev/keycloak-nodejs-example/blob/master/app.js

反正Keycloak应返回GET或PUT请求成功的HTTP代码,如果用户有权限。 你可以只检查它使用curl

http://www.keycloak.org/docs/2.3/authorization_services_guide/topics/service/entitlement/entitlement-api-aapi.html

您使用的资源名称。资源有URI。直接检查URI将会很有趣。但我仍然不知道如何。

您应该始终为Keycloak的每个请求提供access_token。有时,您可以使用admin凭证从Keycloak获取此令牌,使用此URl:auth/realms/master/protocol/openid-connect/tokenmaster是预定义领域的名称)。

但是对于授权API,您需要一个当前用户令牌,因为Keycloak应该了解女巫用户评估权限。

您可以使用https://jwt.io/解码RPT令牌。这只是具有权限的JSON。如果您执行GET权利请求,您将拥有所有权限。对于POST请求,您将只评估权限或FORBIDDEN 403

+0

在我的情况下,客户端是anuglar2应用程序。这意味着对于我的Scala服务器上的anuglar2的每个请求,我必须从头文件中提取令牌并将其发送到keycloak以获取特定资源的用户权限? –

+0

同时,授权api返回和rpt令牌。这个令牌有什么用途?在上面的代码中,我使用从angular2应用程序发送的不记名令牌。 –

+0

@MeisamEmamjome我已经更新了我的答案。我不知道使用此代码'authzClient.entitlement(token).get(resourceServer,request)'执行哪个请求。您是否检查过“FORBIDDEN”回复? –