基于 SAML 响应在 Grails 中分配 Spring 安全角色

Posted

技术标签:

【中文标题】基于 SAML 响应在 Grails 中分配 Spring 安全角色【英文标题】:Assign Spring Security Roles in Grails based on SAML Response 【发布时间】:2019-08-20 19:23:06 【问题描述】:

我正在使用 Grails 3.3.9 中的 Spring Security SAML Grails Plugin。我已阅读文档,但我不明白如何为用户分配角色。我以前使用 Spring Security Core 和 LDAP 插件的组合来验证用户,现在切换到 SAML 以支持单点登录。在 SAML 文档中,我看到需要设置以下内容

Property    | Syntax    | Example Value | Description
userGroupAttribute  | String Value  | 'memberOf'|   Corresponds to the Role Designator in the SAML Assertion from the IDP
userGroupToRoleMapping  | Map [Spring Security Role: Saml Assertion Role]   | [ROLE_MY_APP_ROLE: 'CN=MYSAMLGROUP, OU=MyAppGroups, DC=myldap, DC=example, DC=com']   | This maps the Spring Security Roles in your application to the roles from the SAML Assertion. Only roles in this Map will be resolved.

在我的代码中,我将这些属性设置为:

grails.plugin.springsecurity.saml.userGroupAttribute = 'Group'
grails.plugin.springsecurity.saml.userGroupToRoleMapping = [ROLE_USER:'CN=USERS,CN=Groups,DC=trknow,DC=com',
                                                            ROLE_ADMIN:'CN=ADMINS,OU=Groups,DC=trknow,DC=com']

我使用 ADFS 作为我的 IDP,并且所有属性都从 Microsoft Active Directory 中提取出来。根据我的 idp xml 文件,userGroupAttribute 被命名为 'Group'。

<samlp:Response Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
    Destination="https://sso.trknow.com:8443/sammy/saml/SSO"
    ID="_59831374-4e0c-4664-8431-016293d16ecb" IssueInstant="2019-03-29T19:03:00.075Z" Version="2.0"
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://federation.trknow.com/adfs/services/trust</Issuer>
    <samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
    <Assertion ID="_8a9e9831-1d74-4e74-a5ee-928f3739c663" IssueInstant="2019-03-29T19:03:00.074Z"
        Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        <Issuer>http://federation.trknow.com/adfs/services/trust</Issuer>
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <ds:Reference URI="#_8a9e9831-1d74-4e74-a5ee-928f3739c663">
                    <ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                    <ds:DigestValue>hAeKlB*Truncated*</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>Umiu*Truncated*</ds:SignatureValue>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>MIIC5*Truncated*</ds:X509Certificate>
                </ds:X509Data>
            </KeyInfo>
        </ds:Signature>
        <Subject>
            <NameID>john.willi</NameID>
            <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><SubjectConfirmationData NotOnOrAfter="2019-03-29T19:08:00.075Z"
                Recipient="https://sso.trknow.com:8443/sammy/saml/SSO"/></SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2019-03-29T19:03:00.066Z" NotOnOrAfter="2019-03-29T20:03:00.066Z">
            <AudienceRestriction>
                <Audience>sso.sammy.com</Audience>
            </AudienceRestriction>
        </Conditions>
        <AttributeStatement>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
                <AttributeValue>john.willi@trknow.com</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
                <AttributeValue>Williams</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
                <AttributeValue>John</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/claims/Group">
                <AttributeValue>CN=ADMINS,OU=Groups,DC=trknow,DC=com</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid">
                <AttributeValue>CN=ADMINS,OU=Groups,DC=trknow,DC=com</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
                <AttributeValue>ROLE_ADMIN</AttributeValue>
            </Attribute>
        </AttributeStatement>
        <AuthnStatement AuthnInstant="2019-03-29T19:02:55.635Z"
            SessionIndex="_8a9e9831-1d74-4e74-a5ee-928f3739c663">
            <AuthnContext>
                <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
            </AuthnContext>
        </AuthnStatement>
    </Assertion>
</samlp:Response>

我已经为 saml 插件打开了调试功能。当我进行身份验证时,我看到它说分配了 0 个权限。怎么回事?

2019-03-29 15:03:09.869 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : UserClass class sammy.User
2019-03-29 15:03:09.878 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : Generated User john.willi
2019-03-29 15:03:09.880 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : Loading database roles for john.willi...
2019-03-29 15:03:09.890 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : Returning Authorities with  0 Authorities Added
2019-03-29 15:03:09.890 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : User Class class sammy.User
2019-03-29 15:03:09.890 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : User - username john.willi
2019-03-29 15:03:09.890 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : User - id null
2019-03-29 15:03:09.902 DEBUG --- [nio-8443-exec-9] o.g.p.s.s.SpringSamlUserDetailsService   : User Details grails.plugin.springsecurity.userdetails.GrailsUser@492ab3cb: Username: john.willi; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities

【问题讨论】:

【参考方案1】:

检查 SpringSamlUserDetailsS​​ervice 并查看它如何添加 GrantedAuthority。是否使用 Group 或 Role 元素添加 GrantedAuthority?也许它希望将 group 属性作为元素的名称 http://schemas.xmlsoap.org/claims/Group 而不仅仅是“Group”。

【讨论】:

以上是关于基于 SAML 响应在 Grails 中分配 Spring 安全角色的主要内容,如果未能解决你的问题,请参考以下文章

使用 Grails Spring Security Saml 插件

Spring saml - 在SP上启动登录时如何记住请求参数,并在IdP响应后处理它们

SAML 元数据与 SAML 请求和响应的区别

SAML 2.0 实例分析 idp向sp发送响应

在请求标头中检索 SAML 断言属性的问题

在文本字段中分配和辞职第一响应者