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

如何使用laravel-saml2动态设置Relay State参数?

动态设置SAML认证的RelayState参数实现来源页重定向

步骤1:在登录跳转时传递当前页面URL

当未登录用户需要跳转SAML登录页时,把当前请求的完整URL作为参数传递给saml.login路由:

// 获取当前页面的完整URL(含查询参数)
$currentUrl = url()->full();
return route('saml.login', ['uuid' => 'some-uuid', 'relay_state' => $currentUrl]);

步骤2:创建自定义SamlController并动态设置RelayState

继承原SAML包的控制器(替换成你项目中实际使用的原控制器类),重写login方法来覆盖预定义的relay_state_url:

<?php

namespace App\Http\Controllers;

use OneLogin\Saml2\Auth;
use Illuminate\Http\Request;
// 替换为你项目中原SAML控制器的命名空间路径
use 原SamlController的命名空间路径;

class CustomSamlController extends 原SamlController
{
    public function login(Request $request, $uuid)
    {
        // 从请求中获取传递的来源页URL
        $relayState = $request->get('relay_state');
        
        // 初始化SAML Auth实例(复用原逻辑获取对应租户的SAML配置)
        $auth = new Auth($this->getTenantSamlConfig($uuid));
        
        // 动态设置RelayState,覆盖租户预定义值
        $auth->setRelayState($relayState);
        
        // 触发跳转至IdP的认证页面
        return redirect()->to($auth->login());
    }
    
    // 复用原逻辑获取租户的SAML配置(根据你的业务实现调整)
    private function getTenantSamlConfig($uuid)
    {
        // 示例:从数据库查询对应租户的SAML配置
        $tenant = \App\Models\Tenant::where('uuid', $uuid)->firstOrFail();
        
        return [
            'sp' => [
                'entityId' => $tenant->saml_entity_id,
                'assertionConsumerService' => [
                    'url' => route('saml.acs', ['uuid' => $uuid]),
                ],
                // 其他SP相关配置...
            ],
            'idp' => [
                'entityId' => $tenant->saml_idp_entity_id,
                'singleSignOnService' => [
                    'url' => $tenant->saml_idp_login_url,
                ],
                // 其他IDP相关配置...
            ],
            // 其他全局配置...
        ];
    }
}

步骤3:修改路由指向自定义控制器

在路由文件(如routes/web.php)中,将原来的saml.login路由替换为自定义控制器的方法:

// 替换原saml.login路由
Route::get('/saml/login/{uuid}', [App\Http\Controllers\CustomSamlController::class, 'login'])->name('saml.login');

步骤4:在ACS回调中处理来源页重定向

同样可以在自定义控制器中重写acs方法,获取RelayState并完成安全重定向:

public function acs(Request $request, $uuid)
{
    $auth = new Auth($this->getTenantSamlConfig($uuid));
    $auth->processResponse();
    
    // 校验认证状态
    if (!$auth->isAuthenticated()) {
        return redirect()->route('login')->withErrors('SAML认证失败');
    }
    
    // 获取RelayState参数
    $relayState = $auth->getRelayState();
    
    // 安全校验:仅允许跳转到当前应用域名下的地址,防止开放重定向攻击
    if ($this->isValidRedirect($relayState)) {
        return redirect()->to($relayState);
    }
    
    // 若RelayState无效,跳转至默认页面
    return redirect()->route('dashboard');
}

// 自定义安全校验方法
private function isValidRedirect($url)
{
    $parsed = parse_url($url);
    // 校验域名是否匹配当前应用域名
    return isset($parsed['host']) && $parsed['host'] === parse_url(config('app.url'))['host'];
}

关键注意事项

  • 安全校验不可少:必须对RelayState的URL进行域名校验,避免恶意跳转的安全风险。
  • 配置复用:尽量复用原SAML包中获取租户配置的逻辑,减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:50:14