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?
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
@Table(name="users")
public class User implements UserDetails {
private BigDecimal balance;
// Other properties omitted ...
// Getters and setters omitted ...
// Implementation of UserDetails methods omitted ...
}
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;
}
}
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With