Spring Security - get current custom fields from database

I have a table in my database that 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 am using Spring Security. Part of the configuration:

<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, the current balance of a user in my Spring MVC controller?

+3


source to share


1 answer


The JDBC service defined in the Spring Security configuration will only retrieve the username, password, and status by request users-by-username-query

and by request authorities-by-username-query

. This means that any additional attributes will not be mapped to the primary user object that will be created to populate the security context.

One way to get all of your user's information is to create a custom implementation UserDetailsService

that can retrieve custom data, including all of its custom attributes. Below is an example of this approach (assuming 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

The service responsible for downloading user information. Note that in the real world, you should probably have separate users of DAO queries, program versus frontends, etc. This example is intentionally 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 a AuthenticationProvider

bean and put your custom service as your 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 note, please note that this is not a 100% working copy and paste solution to your problem, but a demonstration of an approach you can take to achieve the desired result. I recommend to view additional documentation on the basic classes / interfaces, such as AuthenticationProvider

, UserDetailsService

, UserDetails

and Spring Security Guide.

+3


source







All Articles