Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security - get current user fields from database

I have a table in my database which contains user information.

CREATE TABLE users
(
  id_user serial NOT NULL,
  phone text,
  password text,
  balance numeric,
  email text,
  CONSTRAINT users_pkey PRIMARY KEY (id_user),
  CONSTRAINT users_login_key UNIQUE (phone)
)

I use Spring Security. Part of the config:

<security:jdbc-user-service id="userService"
        data-source-ref="dataSource"
        users-by-username-query="select phone, password, true from users where phone=?"
        authorities-by-username-query="select phone,'ROLE_USER' from users where phone=?" />

How can I get, for example, current user balance in my Spring MVC Controller?

like image 449
another-programmer Avatar asked Oct 18 '25 15:10

another-programmer


1 Answers

The JDBC service you defined in the Spring Security configuration will only fetch username, password and enabled status using the users-by-username-query query and username's authorities using the authorities-by-username-query query. This means that any extra attributes will not be mapped to the user principal object which will be created to populate the security context.

One way to get all information of your user is to create custom implementation of UserDetailsService which will be able to retrieve user data including all of its custom attributes. Here is an example of this approach (it assumes that you are using JPA/Hibernate for your data layer):

Entity

@Entity
@Table(name="users")
public class User implements UserDetails {
    private BigDecimal balance;
    // Other properties omitted ...
    // Getters and setters omitted ...
    // Implementation of UserDetails methods omitted ...
}

UserService

Service responsible for loading the user information. Note that in real world you should probably have separate DAO querying users, program against interfaces, etc. This example is deliberately kept as short as possible.

@Service
public class UserService implements UserDetailsService {
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public User loadUserByUsername(String username) throws UsernameNotFoundException {
        Query query = sessionFactory.getCurrentSession().createQuery("FROM User u WHERE u.username = :username");
        query.setParameter("username", username);
        User user = (User) query.uniqueResult();
        if (user == null) {
            throw new UsernameNotFoundException("User with username '" + username + "' does not exist.");
        }
        return user;
    }
}

Configuration

Create AuthenticationProvider bean and supply your custom user service as its property.

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <property name="userDetailsService" ref="userService" />
  <!-- Other required properties ... -->
</bean>

Controller

You can access the current user and its properties in the controller using:

User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
BigDecimal balance = user.getBalance();

As a final remark, please note that this is not 100% working copy and paste solution to your problem, rather a demonstration of the approach you can take to achive the desired result. I recommend looking through the documentation of core classes/interfaces such as AuthenticationProvider, UserDetailsService, UserDetails, and Spring Security guides for more details.

like image 194
Bohuslav Burghardt Avatar answered Oct 21 '25 05:10

Bohuslav Burghardt