Keycloak资源授权无适配器

时间:2017-03-08 20:09:51

标签: playframework keycloak

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

  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)

我假设如果服务器返回禁用代码,则具有令牌的用户无权访问该资源。我是在正确的轨道上吗?感谢。

更新

我开发了一个自定义操作来检查标头并验证Authorization toke:

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)
  }
}

2 个答案:

答案 0 :(得分:1)

这可能是一个较晚的答案,但我希望这对其他人有帮助。 version 4.3之后,权利API已被删除。以下是在不使用适配器的情况下使用Keycloak授权时发现的解决方法。

步骤1:

Keycloak Admin UI

中定义策略和权限

第2步

具有一个内部映射,其中包含哪些HTTP路径属于哪些资源以及每个路径所需的作用域。也可以将其保存在configuration file中。当调用特定路由时,请调用Keycloak令牌终结点以验证访问令牌的声明。

{
  "policy-enforcer": {
    "user-managed-access" : {},
    "enforcement-mode" : "ENFORCING"
    "paths": [
      {
        "path" : "/someUri/*",
        "methods" : [
          {
            "method": "GET",
            "scopes" : ["urn:app.com:scopes:view"]
          },
          {
            "method": "POST",
            "scopes" : ["urn:app.com:scopes:create"]
          }
        ]
      }
    ]
  }
}

如果您使用的是适配器,但未指定路径或资源,则适配器将在内部搜索路径和资源from Keycloak

第3步:

使用令牌端点来get or evaluate权限。您可以使用response_mode参数获取最终决定(是否提供访问权限)或检索整个权限。

curl -X POST \
  http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \
  -H "Authorization: Bearer ${access_token}" \
  --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
  --data "permission=Resource A#Scope A"

如果授权请求未映射到任何权限,则将返回403 HTTP状态代码。

答案 1 :(得分: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是预定义域的名称。)

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

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