我正在尝试将 SAML 实现到我的应用程序中,该应用程序由 SPA (Flutter Web) 和 REST API (Springboot) 组成。但我在实现 Flutter 前端应用程序、Springboot Rest API 和 SAML 身份提供程序之间的通信时遇到问题。
目前我已经实现了一个初始 HTTP 请求(@GetMapping("/initial")),该请求在 Flutter 应用程序启动时调用,检查是否配置了 SAML,然后将身份验证发布请求发送到身份提供者。 我的问题是身份提供者将 Rest API 应答到 RestController 中的另一个 Post 映射(@PostMapping("samlsso")。 然后,我为经过身份验证的用户生成一个 Bearer Token,传递给 Flutter 应用程序来处理应用程序中的身份验证状态并自动登录用户。
但是如何将此 token 获取到 Flutter 应用程序呢?由于我使用的是 REST Controller ,所以我不应该在 Controller 中保存任何变量,但为了让 Flutter 应用程序从 Rest API 接收数据,它必须发送对 token 本身的请求。但 Flutter 应用程序不知道 token 何时准备好接收。如何正确实现此通信,而不需要任何手动延迟并将值保存在 RestController 类中的变量中?
PS:我已经尝试从 PostMapping(它接收并处理 SAML 响应)直接向前端发送response.redirect,但我只能通过 header 发送它,而无法从Flutter 应用程序。
后端代码:
@RestController
class SamlController {
var samlToken = ""
@GetMapping("/initial")
fun findToken() {
sendAuthRequestToIdp()
}
@PostMapping("/samlsso")
fun findAll(request: HttpServletRequest, response: HttpServletResponse) {
val user = receiveAndHandleIDPResponse()
//handle errors
val token = generateTokenFromIDPResponse()
samlToken = token
}
@PostMapping("/getSamlToken")
fun findAll(): ResponseEntity<String> {
return ResponseEntity.ok(samlToken)
}
}
前端代码:
Future<String> fetchSamlAuthentication () async {
var jwtString = '';
await launch("api_url/initial"); // launch, so that the IDP website opens in the browser
await Future.delayed(const Duration(milliseconds: 10000));//wait manually until token has been generated
final response = await _client.post(Uri.parse("api_url/getSamlToken"), headers: headers);
jwtString = response.body;
return jwtString;
}
这是我能够使用 SAML 对用户进行身份验证的唯一方法,但它不是一个干净/可用的解决方案。我需要一种更好的方法来将流派 token 获取到 Flutter 应用程序并能够处理它。
最佳答案
SAML 2.0 基于浏览器; IdP 对用户进行身份验证后,IdP 将通过浏览器向应用后端发送 SAML 响应。这可能是您问题中对 POST/samlsso
的调用。
然后,应用程序的后端应验证 SAML 响应,例如根据之前在设置 SAML 连接时获取的 IdP 的 SAML 元数据,检查 SAML 响应中包含的任何签名是否有效。
验证后,应用后端应通过发送重定向响应来完成 POST/samlsso
,其中包含指示用户已通过身份验证的 token 或 cookie。如何完成此操作将取决于您的前端,特别是它是否基于浏览器。
在您的情况下,由于您的应用程序的前端在浏览器中运行,并且您希望对后续请求使用不记名 token (而不是 session cookie),那么您可以在重定向到的 URL 中包含该 token ,这应该是您的 Flutter 应用程序中的一条路线。
当您的 Flutter 应用程序重新加载时,它可以从 URL 检索 token ,并通过每个请求的授权 header 在后续 API 调用中传递它。 希望您的不记名 token 在创建时已由后端签名,以便后端在处理后续请求时可以验证它是否是合法获取的。
关于flutter - 如何在 Flutter Web 前端应用程序和 SpringBoot REST API 中实现 SAML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72300239/