Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security SAML with roles from database

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?

like image 326
Ginkobonsai Avatar asked Oct 24 '25 12:10

Ginkobonsai


1 Answers

1. Is this a good idea and/or the way it's meant to be used?

Yes, You can have custom user object in spring and populate the user details.

2.Will using select username, username as password create a security problem in the app somehow?

No , Spring SAML doesnt expect user password to be stored in user object (rather saml response will be validted by spring). spring will validate username and authority alone. I advise you to just set username and Granted Authorities in user object.

like image 152
meetarun Avatar answered Oct 26 '25 02:10

meetarun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!