playframework - Keycloak资源授权无需适配器

标签 playframework keycloak

我有一个 angular2 客户端连接到由 Play Framework 实现的 Web API。客户端重定向到keycloak服务器获取token。我在他们的 github 项目中遵循了 Keycloak 示例,并且客户端正在工作并获取 token 。不幸的是,我找不到已经为 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)

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

更新:

我开发了一个自定义操作来检查 header 并验证授权 token :

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

最佳答案

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

第 1 步:

Keycloak Admin UI 中定义策略和权限

第 2 步

有一个内部映射,其中包含哪些 HTTP 路径属于哪些资源以及每个路径所需的范围。这也可以保存在configuration file中。当调用特定路由时,调用 Keycloak token 端点来验证访问 token 的声明。

{
  "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 步:

使用 token 端点 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 状态代码。

关于playframework - Keycloak资源授权无需适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42680996/

相关文章:

playframework - Play Framework 功能测试中的 PUT 方法

playframework - Play 框架 ebean 配置

oauth - 使用 Keycloak 和 .NET 核心的基于角色的授权

根据角色将不同的用户重定向到 Keycloak 登录的不同页面

java - Spring安全客户端PKCE与Keycloak

playframework - 使用 h2-browser 访问 Play 项目数据库

dependency-injection - Actor 中的 WebSocket.acceptWithActor 和 @Inject() (Play 2.5)

斯卡拉玩 : How to inject test Database into Controller for testing

javascript - 将用户区域设置包含到 Keycloak ID token 中

backup - Keycloak备份操作