具有数据库角色的 Spring Security SAML
Posted
技术标签:
【中文标题】具有数据库角色的 Spring Security SAML【英文标题】:Spring Security SAML with roles from database 【发布时间】:2016-07-09 18:25:06 【问题描述】:我正在尝试将 SAML SSO 集成到现有应用程序中,该应用程序使用 Spring Security 以及存储在 mysql 数据库中的用户、组和角色/权限。该应用程序当前使用<security:jdbc-user-service>
从数据库中获取用户和角色。有问题的 IDP 仅提供唯一的用户名和电子邮件地址作为属性,因此应用程序仍然必须存储与每个用户本身相关的组和角色(据我所知)。
因此,我尝试通过上下文配置和自定义 SAMLUserDetailsService
将 jdbc-user-service
与 samlAuthenticationProvider
挂钩,从而同时使用 SAML 和 DB。
这是我的applicationContext.xml
的相关部分:
<bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
<property name="userDetails" ref="customUserDetailService" />
</bean>
<bean id="customUserDetailService" class="org.myapp.CustomUserDetailsService">
<property name="jdbcUserService" ref="jdbcUserDetailService" />
</bean>
<bean id="jdbcUserDetailService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource" />
<property name="usersByUsernameQuery" value="select username,username as password,enabled from person where username=?" />
<property name="authoritiesByUsernameQuery" value="select u.username, p.name as authorities
from person u, group g, group_permissions up, permission p
where u.group = g.id and g.id = up.group and up.permissions = p.id and
u.username=?" />
</bean>
这是CustomUserDetailsService
的相关部分:
public class CustomUserDetailsService implements SAMLUserDetailsService
private JdbcDaoImpl jdbcUserService;
@Override
public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException
UserDetails user = null;
String username = credential.getAttributeAsString("urn:mace:dir:attribute-def:cn");
try
user = jdbcUserService.loadUserByUsername(username);
catch (UsernameNotFoundException e)
System.out.println("User not found in DB");
// TODO
return user;
@Autowired
public void setJdbcUserService(JdbcDaoImpl jdbcUserService)
this.jdbcUserService = jdbcUserService;
public JdbcDaoImpl getJdbcUserService()
return jdbcUserService;
我的问题是:以这种方式使用 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 是个好主意吗?
我认为从数据库中检索角色的官方 Spring Security 实现 (JdbcDaoImpl) 比我自己想出的要维护得好、灵活且无错误。
我的第二个问题是:使用select username, username as password
会以某种方式在应用中产生安全问题吗?
由于我的应用程序永远无法看到密码(因为用户只能在 IDP 中输入密码),所以我必须用查询中的内容替换它。我应该注意让这件事变得难以猜测,还是 UserDetails 中的密码无论如何都不会重复使用?
【问题讨论】:
【参考方案1】:1.这是一个好主意和/或它的使用方式吗?
是的,您可以在 spring 中拥有自定义用户对象并填充用户详细信息。
2. 使用选择用户名、用户名作为密码是否会在应用程序中产生某种安全问题?
不,Spring SAML 不希望用户密码存储在用户对象中(而是 saml 响应将由 spring 验证)。 spring 将单独验证用户名和权限。我建议您只在用户对象中设置用户名和授予权限。
【讨论】:
与以下相同:这不能回答我想问的问题。我已经稍微编辑了这个问题 - 我希望它更清楚我所追求的。我主要关心的是:我是否应该以这种方式连接 JdbcDaoImpl 和 SAMLAuthenticationProvider,重用 JdbcDaoImpl 的数据库访问功能,而不是自己实现它。一旦你使用了 JdbcDaoImpl,你必须为密码提供一些东西,但这并不重要。 @Ginkobonsai spring 永远不会使用 userdetails 对象中的密码...(它使用用户名和授予权限)您可以将其存储为空/带有垃圾值.. 对于每个请求,spring 将进一步只检查 saml 断言令牌和用户的角色。【参考方案2】:考虑如下图:
它描述了基于 SAML 的身份验证过程的所有典型步骤。
请求受保护资源的用户将从服务提供商(依赖方)重定向到第三方身份提供商。 用户在身份提供者上执行身份验证(即同时提供用户名/密码、OTP、PIN 码等)。 如果身份验证成功,身份提供者会向服务提供者发回一个 SAML 信封。它包含存储在 SAML 断言中的用户的个人资料信息(名字、姓氏、电子邮件、电话号码、组织等),根据双方之间的属性释放协议。用户也会被重定向回服务提供商。此时,由于双方之间的信任关系,IdP正在为用户身份做担保。您不再需要询问密码,因为 AuthN 过程已完成。 此时您通常需要的是管理资源访问控制的信息,即授权 (AuthZ)。通常使用角色模型 (RBAC) 执行 AuthZ:
The user "jdoe" is authenticated.
The user "jdoe" has "StandardUser" as role.
The resource A is available only for "Administrator".
The user "jdoe" is not authorised to access to the resource A.
还有:
The user "jdoe" is authenticated.
The user "jdoe" has "StandardUser" as role.
The resource B is available only for "StandardUser".
The user "jdoe" is authorised to access to the resource B.
考虑到所有用户的角色都存储在本地数据库中,您必须检索执行数据访问的那些信息才能匹配身份和角色。
所以:
这是一个好主意和/或它的使用方式吗?
loadUserBySAML
方法应该识别 SAML 断言中的数据引用的用户的本地帐户,并返回描述用户的 UserDetails
对象。此时,您还应该根据某个用户在您的应用程序域中的角色授予适当的权限。
本地数据检索实现由您决定。您可以使用标准访问,对数据库执行直接查询,或者根据 JPA 规范(参见 Spring Data)实现现代数据访问模型,同时使用 ORM。 p>
使用选择用户名、用户名作为密码会以某种方式在应用中造成安全问题吗?
如前所述,您无需对应用程序执行用户凭据验证,因为您使用的是基于 SAML 的身份验证。 SSO 实际上旨在不共享密码等关键信息。
【讨论】:
嗯,这并不能回答我想问的问题。我已经稍微编辑了这个问题 - 我希望它更清楚我所追求的。我主要关心的是:我是否应该以这种方式连接 JdbcDaoImpl 和 SAMLAuthenticationProvider,重用 JdbcDaoImpl 的数据库访问功能,而不是自己实现它。一旦你使用了 JdbcDaoImpl,你必须为密码提供 something 但这并不重要。以上是关于具有数据库角色的 Spring Security SAML的主要内容,如果未能解决你的问题,请参考以下文章
具有 Active Directory 和数据库角色的 Spring Security
Spring Security:检查用户是不是具有分层角色的方法
拒绝Spring Security中具有相同角色的多个用户的访问
具有角色的经过身份验证的用户的 Spring Security Java 配置