如何在 Spring Security 中更新另一个用户的状态?

Posted

技术标签:

【中文标题】如何在 Spring Security 中更新另一个用户的状态?【英文标题】:How to update state of another user in Spring Security? 【发布时间】:2019-01-25 21:17:18 【问题描述】:

假设User 可以喜欢Posts。当帖子被点赞时,帖子作者(另一个User)的得分会增加。我在数据库中更新作者的状态:

post.getAuthor().incrementScore(LIKE_SCORE);
postRepository.save(post); \\ author is also updated

但问题是,如果作者当前已登录,则更改不会反映给他,他应该重新登录才能看到他的更新分数。

如何在 Spring Security 中更新另一个经过身份验证的用户的状态?请注意,我没有将用户添加到我的控制器,而是直接在模板中访问主体。我做错了吗?

用户实体:

@Entity
@EqualsAndHashCode(of = "username")
public class User implements UserDetails 

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;

    @ManyToMany(mappedBy = "likers", fetch = EAGER)
    private Set<Post> favorites = new HashSet<>();

    @OneToMany(mappedBy = "author", fetch = EAGER)
    private Set<Post> posts = new HashSet<>();

    @NaturalId
    private String username;

    private String password;

    private long score;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() 
        return Set.of(new SimpleGrantedAuthority("ROLE_" + role));
    

    @Override
    public String getPassword() 
        return password;
    

    @Override
    public String getUsername() 
        return username;
    

    // other overridden methods, getters and setters

安全配置:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.userDetailsService(userDetailsService).passwordEncoder(encoder);


@Override
protected void configure(HttpSecurity http) throws Exception 
    http.authorizeRequests().anyRequest().permitAll()
        .and().formLogin().usernameParameter("username").passwordParameter("password")
        .loginProcessingUrl("/login")
        .successHandler((request, response, authentication) ->
                    response.getOutputStream().print(true))

        .failureHandler((request, response, exception) ->
                    response.getOutputStream().print(""))

        .and().logout()
        .logoutSuccessHandler((request, response, authentication) ->
                    response.sendRedirect(request.getHeader("referer")))

        .and().cors().disable();

Thymeleaf 模板:

<div class="nav">
  <div class="author">
    <div class="usr-name" th:text="$#authentication.principal.username"></div>
    <div class="score" th:text="$#authentication.principal.score"></div>
  </div>
</div>

【问题讨论】:

如何加载用户?您是否将用户保存在 HTTP 会话中。显示你的 Spring Security 配置和你的控制器,它会显示分数。 【参考方案1】:

您可以使用服务器发送的事件(sse)http 流的变体。这是通过 http 向侦听器推送事件。 Springboot 有 SseEmitter 类来支持 sse

查看使用 sse https://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/sse-emitter.html 进行服务器推送的示例

【讨论】:

以上是关于如何在 Spring Security 中更新另一个用户的状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何在spring security java config中通过jsp表单更新用户详细信息

成功登录后如何更新 Spring Security UserDetails impls?

使用 Spring Security 成功登录后如何正确更新登录日期时间?

如何强制 Spring Security 更新 XSRF-TOKEN cookie?

使用 Spring Security 成功登录后如何正确更新登录日期时间?

使用 Spring Security 更新角色时如何注销用户