【问题标题】:Spring Security - get current user fields from databaseSpring Security - 从数据库中获取当前用户字段
【发布时间】:2015-07-21 01:05:30
【问题描述】:

我的数据库中有一个包含用户信息的表。

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。部分配置:

<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 控制器中获取当前用户余额?

【问题讨论】:

  • 您可以实现自定义UserDetailsService,您可以在其中检索用户详细信息并将它们映射到某种实现UserDetails的模型对象,该对象还将包含其他字段,例如余额等。然后您可以检索来自SecurityContextHolder 的控制器中的用户对象并访问其属性。
  • 谢谢,我试试!你能写一些示例代码吗?

标签: java spring spring-mvc spring-security


【解决方案1】:

您在 Spring Security 配置中定义的 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% 有效的复制和粘贴解决方案,而是您可以采取的实现预期结果的方法的演示。我建议查看核心类/接口的文档,例如 AuthenticationProviderUserDetailsServiceUserDetails 和 Spring Security 指南以了解更多详细信息。

【讨论】:

  • @Bohuslav 如何使用用户 user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); BigDecimal 余额 = user.getBalance();在 jsp 文件中的任何建议
  • 对我不起作用!我得到class org.springframework.security.core.userdetails.User cannot be cast to class gr.hua.dit.distributedsystemsexercise.team1.internal.service.SupervisorPrincipal
猜你喜欢
  • 2021-01-23
  • 2015-06-02
  • 2014-06-10
  • 2020-02-12
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 2013-02-07
相关资源
最近更新 更多