【发布时间】: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 中的密码无论如何都不会重复使用?
【问题讨论】:
标签: java spring spring-security spring-saml