如何使用 Spring Security 和 Thymeleaf 获取当前登录用户的 ID

Posted

技术标签:

【中文标题】如何使用 Spring Security 和 Thymeleaf 获取当前登录用户的 ID【英文标题】:How to get ID of currently logged in user using spring security and Thymeleaf 【发布时间】:2018-01-25 18:08:12 【问题描述】:

我在我的项目和 Thymeleaf 视图中使用 Spring 安全性。我正在尝试获取当前登录用户的 ID,以便我可以将它用于我的某些方法。

例如,我正在尝试将用户添加到一个类。在 html 部分我有这样的按钮。

<td th:each="user : $user">
    <a th:href="@/userList/user_id/saveClasses/classes_id (user_id=$user.id, classes_id=$classes.id)">Attend</a>
</td>

当我运行我的代码时,我会为我在数据库中拥有的 2 个用户获得 2 个出席按钮。 我想为当前已登录的用户设置一个按钮。我该怎么做?

为了显示登录用户的用户名,我使用这个:

<span sec:authorize="isAuthenticated()"> 
    <a class="navbar-brand" href="#">Hello <span sec:authentication="name"></span></a>
</span>

【问题讨论】:

【参考方案1】:

解决方案


花了几个小时试图找到答案后,终于找到了适合我的解决方案。

我已经使用存储库完成了,这是我的实现:

UserRepository.java

@Repository
public interface UserRepository extends CrudRepository<User, Long>, UserDetailsService 

     public User findUserByUsername(String username);


UserRepositoryImpl

公共类 UserRepositoryImpl 实现 UserDetailsS​​ervice

@Autowired
 private UserRepository userRepository;

 @Override
 public UserDetails loadUserByUsername(String username) 
  return userRepository.findUserByUsername(username);
 

controller.java

@RequestMapping("/dashboardUser")
    public String dashboardPageList(Model model, @AuthenticationPrincipal UserDetails currentUser ) 
    User user = (User) userRepository.findUserByUsername(currentUser.getUsername());
        model.addAttribute("currentStudent", user);

        return "dashboardUser";
    

在 .html 文件中我是这样显示的

<div class="form-group label-floating">
    <label>Username</label> 
    <input type="text" name="username" 
    th:value="$currentStudent.username"/>
</div>

【讨论】:

【参考方案2】:

据我所知,$user 您拥有数据库中的用户列表。 我在这里看到两个选项。

    您可以在控制器中添加到Model 当前登录的用户:

    public String foo(Model model) 
        User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username = user.getUsername();
        model.addAttribute("username", username);
        return "your_view";
    
    

    然后在你的 html 中:

    <td th:each="user : $user">
        <a th:if="$username == user.username" th:href="@/userList/user_id/saveClasses/classes_id (user_id=$user.id, classes_id=$classes.id)">Attend</a>
    </td>
    

    在您的th:each 中,您可以添加th:if 以检查user 当前是否已登录。这里也有几种方法。其中之一是:

    <td th:each="user : $user">
        <a th:if="$#authentication.getName() == user.username" th:href="@/userList/user_id/saveClasses/classes_id (user_id=$user.id, classes_id=$classes.id)">Attend</a>
    </td>
    

    如果您有数据库,您可能有模型 - here 您可以找到详细说明如何使用您的自定义类为用户执行此操作。 1 和 2 选项在您的情况下是最简单的,但这个更优雅。

在我的解决方案中,来自数据库的用户需要字段 username。 此外,我建议将用户列表保存在名为 users 的变量中,而不是 user - 它更具可读性。

【讨论】:

使用第一个选项,我如何获取当前登录用户的 ID?我可以看到我得到用户名,就是这样。我已经做到了。在第二种选择中,我会得到身份证吗?使用th:each="user : $user",我将再次在行中有多个参加按钮,因为我将用户存储在数据库中。我只想要当前登录的用户。 @Nequeq 我添加了它,但我得到了这个错误:ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to com.oggi.model.User你知道为什么吗? 好吧,我搞错了。 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 返回实现interface UserDetails - link 的User 类。您的类必须实现此接口,然后您应该能够将其转换为UserDetails 而不是User。试试这个,让我知道。 我有一个问题,这个方法在我的控制器内部。我再次更新了我的问题以显示它的样子。当我用这行代码long id = user.getId();在其中实现UserDetails时,我无法获得ID,我只能获得Authorities()、class()、password()和username()。 @Nequeq Here 你有完整的例子。

以上是关于如何使用 Spring Security 和 Thymeleaf 获取当前登录用户的 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Security thymeleaf sec 中使用列表:授权标签

在 org.springframework.security.web.access.expression.WebSecurityExpressionRoot 类型上找不到 Spring Boot Th

Spring Security Ajax 被拦截

微服务和 Spring Security OAuth2

Spring Boot整合Spring Security总结

使用 Spring Security 时出现意外的 403 错误