Spring 安全 - 从数据库中获取当前用户字段
Spring Security - get current user fields from database
我的数据库中有一个 table,其中包含用户信息。
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)
)
我使用 Spring 安全。部分配置:
<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=?" />
例如,如何在我的 Spring MVC 控制器中获取当前用户余额?
您在 Spring 安全配置中定义的 JDBC service 将仅使用 users-by-username-query
查询获取用户名、密码和启用状态,使用 authorities-by-username-query
查询获取用户名权限.这意味着任何额外的属性都不会映射到将创建以填充安全上下文的用户主体对象。
获取用户所有信息的一种方法是创建 UserDetailsService
的自定义实现,它将能够检索用户数据,包括其所有自定义属性。下面是这种方法的一个示例(它假设您正在为数据层使用 JPA/Hibernate):
实体
@Entity
@Table(name="users")
public class User implements UserDetails {
private BigDecimal balance;
// Other properties omitted ...
// Getters and setters omitted ...
// Implementation of UserDetails methods omitted ...
}
用户服务
服务负责加载用户信息。请注意,在现实世界中,您可能应该有单独的 DAO 查询用户、针对接口的程序等。此示例故意保持尽可能短。
@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;
}
}
配置
创建 AuthenticationProvider
bean 并提供自定义用户服务作为其 属性。
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userService" />
<!-- Other required properties ... -->
</bean>
控制器
您可以使用以下方法在控制器中访问当前用户及其属性:
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
BigDecimal balance = user.getBalance();
最后一点,请注意,这不是针对您的问题的 100% 有效的复制和粘贴解决方案,而是演示您可以采用哪些方法来获得所需的结果。我建议查看核心 classes/interfaces 的文档,例如 AuthenticationProvider
、UserDetailsService
、UserDetails
和 Spring 安全指南以获取更多详细信息。
我的数据库中有一个 table,其中包含用户信息。
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)
)
我使用 Spring 安全。部分配置:
<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=?" />
例如,如何在我的 Spring MVC 控制器中获取当前用户余额?
您在 Spring 安全配置中定义的 JDBC service 将仅使用 users-by-username-query
查询获取用户名、密码和启用状态,使用 authorities-by-username-query
查询获取用户名权限.这意味着任何额外的属性都不会映射到将创建以填充安全上下文的用户主体对象。
获取用户所有信息的一种方法是创建 UserDetailsService
的自定义实现,它将能够检索用户数据,包括其所有自定义属性。下面是这种方法的一个示例(它假设您正在为数据层使用 JPA/Hibernate):
实体
@Entity
@Table(name="users")
public class User implements UserDetails {
private BigDecimal balance;
// Other properties omitted ...
// Getters and setters omitted ...
// Implementation of UserDetails methods omitted ...
}
用户服务
服务负责加载用户信息。请注意,在现实世界中,您可能应该有单独的 DAO 查询用户、针对接口的程序等。此示例故意保持尽可能短。
@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;
}
}
配置
创建 AuthenticationProvider
bean 并提供自定义用户服务作为其 属性。
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userService" />
<!-- Other required properties ... -->
</bean>
控制器
您可以使用以下方法在控制器中访问当前用户及其属性:
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
BigDecimal balance = user.getBalance();
最后一点,请注意,这不是针对您的问题的 100% 有效的复制和粘贴解决方案,而是演示您可以采用哪些方法来获得所需的结果。我建议查看核心 classes/interfaces 的文档,例如 AuthenticationProvider
、UserDetailsService
、UserDetails
和 Spring 安全指南以获取更多详细信息。