You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala服务作为SP,如何通过pac4j-saml 6.0.2触发SAML登录流程?

使用pac4j-saml 6.0.2触发SAML登录流程指引

问题背景

你有一个作为服务提供商(SP)的Scala服务,基于pac4j-saml 6.0.2版本对接Keycloak身份提供商(IdP)实现SAML认证。已定义如下路由和SAML配置,但不清楚如何通过访问/login触发SAML登录流程:

现有路由(routes.scala)

path("login"){
   get {
    complete(StatusCodes.OK -> "OK")
  }
}

现有SAML配置(SAMLConfigObject.scala)

class SAMLConfigObject {
  def constructConfigObject: Config = {
     val saml2Configuration = new SAML2Configuration()
     saml2Configuration.setKeystorePath("samlKeystore.jks")
     saml2Configuration.setKeystorePassword("pac4j-demo-passwd")
     saml2Configuration.setPrivateKeyPassword("pac4j-demo-passwd")
     saml2Configuration.setIdentityProviderMetadataPath("http://localhost:9090/realms/IdProvider/protocol/saml/descriptor")
     saml2Configuration.setIdentityProviderEntityId("http://localhost:9090/realms/IdProvider")
     val saml2Client: SAML2Client = new SAML2Client(saml2Configuration)
     saml2Client.setName("SAML2Client")
     val config =  new Config(saml2Client)
     config
  }
}

解决方案步骤

1. 添加pac4j Akka HTTP依赖

确保你的build.sbt中包含适配pac4j 6.x版本的Akka HTTP集成包:

libraryDependencies += "org.pac4j" %% "pac4j-akka-http" % "6.0.2"

2. 修改/login路由触发SAML认证

替换现有/login路由逻辑,使用pac4j的AuthenticateAction触发重定向到Keycloak的SAML登录页面:

import org.pac4j.akka.http.AuthenticateAction
import org.pac4j.core.config.Config
import akka.http.scaladsl.server.Directives._

// 初始化SAML配置实例
val samlConfig = new SAMLConfigObject().constructConfigObject

path("login") {
  get {
    // 指定使用SAML2Client触发认证流程
    AuthenticateAction(samlConfig, Some("SAML2Client"))
  }
}

3. 添加回调路由处理IdP响应

Keycloak验证用户身份后,会将SAML断言回调到SP的指定路径,需新增路由处理该回调:

import org.pac4j.akka.http.CallbackAction

path("callback") {
  get {
    // 解析SAML响应,完成认证会话建立
    CallbackAction(samlConfig)
  }
}

4. 完善SAML配置细节

现有配置缺少SP侧关键参数,需补充以匹配Keycloak的SP客户端配置:

class SAMLConfigObject {
  def constructConfigObject: Config = {
     val saml2Configuration = new SAML2Configuration()
     saml2Configuration.setKeystorePath("samlKeystore.jks")
     saml2Configuration.setKeystorePassword("pac4j-demo-passwd")
     saml2Configuration.setPrivateKeyPassword("pac4j-demo-passwd")
     saml2Configuration.setIdentityProviderMetadataPath("http://localhost:9090/realms/IdProvider/protocol/saml/descriptor")
     saml2Configuration.setIdentityProviderEntityId("http://localhost:9090/realms/IdProvider")
     // 新增:SP实体ID(需与Keycloak中配置的SP实体ID完全一致)
     saml2Configuration.setServiceProviderEntityId("http://localhost:8080/callback")
     // 新增:SP元数据生成地址,用于Keycloak导入SP配置
     saml2Configuration.setServiceProviderMetadataPath("http://localhost:8080/callback?metadata=true")
     // 启用SP元数据自动生成
     saml2Configuration.setGenerateServiceProviderMetadata(true)

     val saml2Client: SAML2Client = new SAML2Client(saml2Configuration)
     saml2Client.setName("SAML2Client")
     val config = new Config(saml2Client)
     // 配置会话存储(默认内存存储,生产环境可替换为分布式存储)
     config.setSessionStore(new org.pac4j.core.context.session.SessionStore())
     config
  }
}

5. 验证Keycloak配置一致性

确保Keycloak中你的SP客户端配置与上述参数匹配:

  • 实体ID:与setServiceProviderEntityId的值完全一致
  • Valid Redirect URIs:包含回调URL(如http://localhost:8080/callback)
  • SAML元数据源:可通过http://localhost:8080/callback?metadata=true获取并导入Keycloak

流程说明

当用户访问/login时,AuthenticateAction会根据SAML配置生成重定向URL,引导用户到Keycloak的登录页面。用户完成身份验证后,Keycloak会将SAML断言发送到/callback路由,CallbackAction会解析断言、建立用户会话,之后你可以通过ProfileAction获取用户信息,或使用RequireAuthenticationAction保护需要登录才能访问的路由。

内容的提问来源于stack exchange,提问作者ntj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:33:18