Spring Security SAML with roles from database

Viewed 4086

I'm trying to integrate SAML SSO into an existing application that uses Spring Security with users, groups, and roles/permissions stored in a MySQL database. The application currently uses <security:jdbc-user-service> to get users and roles from the DB. The IDP in question offers only a unique username and an email address as attributes, so the application still has to store groups and roles associated with each user itself (as far as I understand).

So, I trying using both SAML and the DB by hooking the jdbc-user-service up with the samlAuthenticationProvider through the context configuration and a custom SAMLUserDetailsService.

Here's the relevant part of my 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>

And this is the relevant part of 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;
    }
}

My question is: Is this a good idea to use org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl in this way?

I figured that the official Spring Security implementation (JdbcDaoImpl) of role retrieval from a DB is much more well-maintained, flexible, and bug-free than what I would come up with myself.

My second question is: Will using select username, username as password create a security problem in the app somehow?

Since my app never gets to see the password (because the user only enters it at the IDP), I have to replace it with something in the query. Should I take care to make this something hard to guess or is the password in the UserDetails not re-used anyway?

2 Answers
Related