cirrusidentity/simplesamlphp-module-cirrusgeneral

Cirrus Identity 开发的各种过滤器 SSP 模块

v3.0.0-alpha.2 2023-10-26 23:35 UTC

README

目录 DocToc 生成

安装

对于 SSP 2,使用模块的版本 3

composer require cirrusidentity/simplesamlphp-module-cirrusgeneral:v3.0.0-alpha.1

对于 SSP 1.X,使用模块的版本 2

修改元数据源

通常需要调整 entityId 的元数据以修复某些值或添加特定于 SSP 的配置项。如果元数据是从远程源加载的,则很难实现。 ModifyingMetadataSource 允许您配置不同的策略来更改加载的元数据。源将委托给其他源(如 mdq 或序列化源),然后在返回之前编辑元数据。

 'metadata.sources' => [
            [
                'type' => 'SimpleSAML\Module\cirrusgeneral\Metadata\Sources\ModifyingMetadataSource',
                // Any sources that you want to delegate to
                'sources' => [
                    array('type' => 'flatfile', 'directory' => __DIR__ . '/testMetadata'),
                    array('type' => 'flatfile', 'directory' => __DIR__ . '/testMetadata2'),
                ],
                'strategies' => [
                    ['type' => 'SimpleSAML\Module\cirrusgeneral\Metadata\AdfsMetadataStrategy'],
                    [
                        'type' => 'SimpleSAML\Module\cirrusgeneral\Metadata\OverridingMetadataStrategy',
                        'source' => array('type' => 'flatfile', 'directory' => __DIR__ . '/overrideMetadata'),
                    ],
                    [
                        'type' => 'SimpleSAML\Module\cirrusgeneral\Metadata\PhpMetadataStrategy',
                        // Run php code to edit the metadat. Defined variables are $metadata, $set, and $entityId
                        'code' => '
                             if ($set === "saml20-sp-remote") {
                                $metadata["attributes"] = $metadata["attributes"] ?? ["attr1", "attr2"];
                             } 
                        '
                    ]                    
                    // some other strategy
                    // ['type' => 'Myclass', 'configOption1' => true],
                ],
            ],
            // Any sources that you don't want to pass to the modifying strategis
            // [ 'type' => 'flatfile' ],
        ]

策略

AdfsMetadataStrategy

disable_scoping 添加到看起来像 ADFS 的任何元数据中

OverridingMetadataStrategy

从源加载附加元数据,并将其与主元数据结合使用。对于 saml20-sp-remoteflatfile 覆盖策略将查找文件 saml20-sp-remote-override.php,然后返回元数据作为 $overrideMetadata + $unalteredMetadata,这将保留覆盖元数据中的键,如果常规元数据中存在相同的键。

PhpMetadtaStrategy

此策略允许您运行 PHP 代码片段以调整元数据。您的代码将可用 3 个变量:数组 $metadata、字符串 $set 和字符串 $entityId。$metadata 将包含实体的当前元数据,并且您的代码可以对此数组进行更改。

如果您有复杂的代码逻辑,您最好创建自己的策略并编写单元测试。

AttributeSplitter

此 AuthProc 过滤器将根据分隔符拆分属性值并将其转换为数组。某些系统将多值属性(如 eduPersonAffiliation)存储为逗号分隔的列表 - student,member 此过滤器将将其拆分为多个值

用法

// In your authProc config
    20 => [
        'class' => 'cirrusgeneral:AttributeSplitter',
        'delimiter' =>  ',',  // Optional. Default is comma
        'attributes' => ['eduPersonAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.1'],
    ]

AttributeValueMapper

根据 csv 文件或 PHP 配置将源属性名称和值映射到新的属性名称和值。在数据源(用于组、权限等)包含需要映射到新内容的名称和值时很有用。

// In your authProc config
    20 => [
        'class' => 'cirrusgeneral:AttributeValueMapper',
        'csvFile' =>  '/patch/to/csv',
         'mappingLookup' => [
                // source attribute name
                'inc-eduPersonEntitlement' => [
                     // source value
                     'inc-eduPersonEntitlement-everfi' => [
                           // dest attribute      =>   [ dest val1, dest val2]
                           'eduPersonEntitlement' => ['val1', 'val2'],
                           'localEntitlement' => ['anotherValue'],
                     ]
                ],
         ]
    ]

CSV 文件格式

每行包含一个源属性和值,如果用户具有该值的属性,则将填充 destinationAttribute 以包含 destinationValue。将删除重复项

sourceAttribute,sourceValue,destinationAttribute,destinationValue
group-test,newStudent,eduPersonAffiliation,student
group-med,newStudent,eduPersonAffiliation,student
group-test,newStudent,eduPersonAffiliation,member
group-test,oldStudent,eduPersonAffiliation,alumni
group-test,incoming-Student,eduPersonAffiliation,student
group-test,incoming-Student,entitlement,https://example.com/checkfinacialAid
group-test,newStudent,entitlement,urn:blah:blahstudent-app
group-med,med-student,eduPersonAffiliation,student
group-med,med-student,eduPersonAffiliation,other
group-med,newStudent,entitlement,urn:med:student-app
group-med,faculty,entitlement,urn:med:faculty-app

PromptAttributeRelease

如果用户具有多值属性且 SP 只能使用/期望一个值,则 PromptAttributeRelease 过滤器可以提示用户选择应发布到 SP 的值。例如,SP 根据不同的 eduPersonAffiliation 值具有不同的功能。此过滤器将允许用户选择要发布哪个隶属关系。

// In your authProc config
    20 => [
        'class' => 'cirrusgeneral:PromptAttributeRelease',
         'attribute' => 'eduPersonAffiliation',
         // optional labels to prefix in front of values
         'labels' => [
             'student' => 'Student Role',
             'member'  => 'Generic Role'
             // any other values don't get a label and are shown as the plain value in the UI
         ]
         // optional: should the attribute value be shown after the label? defaults to true
         'displayAttributeValue' => false

ConditionalSetAuthnContext

此AuthProc过滤器允许您在用户状态中的值等于某些预期值时断言特定的authnContextClassRef。例如,某些上游系统可能会通过在用户上设置一个属性来指示用户需要执行多因素认证。如果存在该属性,此过滤器将允许您断言https://refeds.org/profile/mfa

用法

// In your authProc config of your IdP
    20 => [
        'class' => 'cirrusgeneral:ConditionalSetAuthnContext',
        'path' => ['Attributes', 'mfaActivated'], // The path of keys to traverse in the request state,
        'value' =>  'true',  // Using the string 'true' rather than a boolean true
        'contextToAssert' => 'https://refeds.org/profile/mfa',
        'ignoreForEntities' => ['match1', 'match2', 'other']

        // Optional context to assert if there is no match
        // 'elseContextToAssert' => 'https://refeds.org/profile/sfa'
    ]

// Example for Okta
      25 => array(
                    'class' => 'cirrusgeneral:ConditionalSetAuthnContext',
                    'path' => ['Attributes', 'session.amr'],
                    'value' => 'mfa',
                    'contextToAssert' => 'https://refeds.org/profile/mfa',
                ),

// Exmample for Aure AD
      49 => array(
                    'class' => 'cirrusgeneral:ConditionalSetAuthnContext',
                    'path' => ['Attributes', 'http://schemas.microsoft.com/claims/authnmethodsreferences'],
                    'value' => 'http://schemas.microsoft.com/claims/multipleauthn',
                    'contextToAssert' => 'https://refeds.org/profile/mfa',
                ),

AttributeRemove

此AuthProc过滤器允许您定义应始终删除的属性。我们与AzureAD一起使用它,因为它总是返回一些额外的属性(如tenantId),我们希望从用户属性中删除。

用法

// In your authProc config
    20 => [
        'class' => 'cirrusgeneral:AttributeRemove',
        'attributes' => ['http://schemas.microsoft.com/identity/claims/tenantid', 'http://schemas.microsoft.com/identity/claims/objectidentifier'],
        'attributeRegexes' => ['/^operational/']
    ]

ObjectSidConverter

ActiveDirectory的objectSid可以是二进制格式或格式化的字符串。有时您会收到一个,但期望另一个。

Conditional AuthProc 插入

存在一些用例,您希望运行一组authproc过滤器,但仅在用户登录时满足某些条件。并非所有authproc过滤器都支持条件使用。BaseConditionalAuthProcInserter的子类允许您在authproc处理期间在BaseConditionalAuthProcInserter优先级处插入任意数量的authproc过滤器。这允许您在创建过滤器之前检查用户状态中的内容。

PhpConditionalAuthProcInserter

PhpConditionalAuthProcInserter是定义一个布尔表达式以确定是否创建authproc过滤器的示例。有两个变量可用:array $attributesarray $state

// In your authsources.php or saml20-idp-metadata.php or whereever you define your authprocs
   'authproc' => [
       10 => [
           // a norma authproc
           'core:AttributeMap'
       ],
       20 => [
             'class' => 'cirrusgeneral:PhpConditionalAuthProcInserter',
             //php boolean expression. Two variables are available: $attributes and $state
            'condition' => 'return $state["saml:sp:State"]["saml:sp:AuthnContext"] === "https://refeds.org/profile/mfa";',
             // These will only get created if AuthnContext is refeds MFA, and they will run immediately after
             // PhpConditionalAuthProcInserter
             'authproc' => [
                [
                  'class' => 'core:AttributeAdd',
                  'newAttribute' => array('newValue'),
                ],
                [
                   'class' => 'core:AttributeMap',
                ],
             ],
             // These will only get created if authnContext is not refeds MFA
             'elseAuthproc' => [
                [
                  'class' => 'somemodule:PerformMfa',
                ],
                [
                   'class' => 'somemodule:SetRefedsMfa',
                ],
             ]
       ],
       30 => [
          // another normal authproc
          'core:AttributeMap'
       ]


   ]

开发

运行phpcs以检查代码风格

./vendor/bin/phpcs

运行phpunit进行测试

./vendor/bin/phpunit

您可以使用phpcs自动纠正一些发现。建议您在部署更改(或甚至在提交后)之后这样做,因为有可能只是弄乱您的代码。

./vendor/bin/phpcbf

运行psalm以查找问题

./vendor/bin/psalm   --no-cache

使用 Docker 探索

您可以使用Docker探索这些功能。

docker run -d --name ssp-cirrusgeneral \
   --mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/cirrusgeneral,readonly \
  -e STAGINGCOMPOSERREPOS=cirrusgeneral \
  -e COMPOSER_REQUIRE="cirrusidentity/simplesamlphp-module-cirrusgeneral:@dev" \
  -e SSP_ENABLED_MODULES="cirrusgeneral" \
  --mount type=bind,source="$(pwd)/tests/docker/metadata/",target=/var/simplesamlphp/metadata/,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/cert/",target=/var/simplesamlphp/cert/,readonly \
   -p 443:443 cirrusid/simplesamlphp:v2.0.0

然后以admin:secret登录到https://cirrusgeneral.local.stack-dev.cirrusidentity.com/simplesaml/module.php/core/frontpage_welcome.php以确认一切工作正常。

尝试的事项

属性提示/选择器

Idp为eduPersonAffiliation属性启用了PromptAttributeRelease authproc过滤器。如果用户有多个值,他们需要选择要释放的值。有关可用用户的信息,请参阅authsources.php。为了使IdP运行其authproc过滤器,您需要从SP发送一个登录,而sp-auth源将执行此登录。