如何使用 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 实现 UserDetailsService
@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