Spring security Principal 不适用于@PostConstruct

Posted

技术标签:

【中文标题】Spring security Principal 不适用于@PostConstruct【英文标题】:Spring security Principal won't work with @PostConstruct 【发布时间】:2020-12-02 20:49:27 【问题描述】:

我有一个 managedbean,其中包含返回登录用户的用户名的函数:

public String getConnectedUser( )  
    SecurityContext context = SecurityContextHolder.getContext();
    Authentication authentication = context.getAuthentication();
    if (authentication == null)
        return null;
    Object principal = authentication.getPrincipal();
    if (principal instanceof UserDetails) 
        return ((UserDetails) principal).getUsername();
     else 
        return principal.toString();
    

我想使用我从 spring security 获得的用户名让用户使用我的 DAO。 当我在 @PostConstruct 方法中调用它时,它不会返回任何内容。

    @PostConstruct
public void init() 

user = utilisateurService.getUtilisateurByLogin( getConnectedUser());

但是当我在 JSF 中调用它时,它会显示正确的登录用户名:

        <h:outputText
            value="Logged as : #testMB.getConnectedUser()" />

结论:使用 Init 函数我在视图中什么也得不到,通过 JSF 调用我得到用户名,有人可以帮助我吗?

编辑:我运行了一些测试,似乎身份验证为空,即使我已登录

【问题讨论】:

为什么在 PostConstruct 中需要它?您不能在常规 DAO 调用期间调用该方法吗?到那时应该可以使用。 @SKumar 我把它放在 PostConstruct 中,因为我猜初始化发生在那里?我尝试在 service/dao 中输入它并从 PostConstruct 中调用它,我想我没有清楚地理解你,请向我解释更多 【参考方案1】:

我认为 Spring Security 主体在 PostConstruct 中不可用是有道理的。

DAO 上的 PostConstruct 将在应用程序启动时被调用。那时,将没有登录用户。但是,当您浏览 JSF 页面时,您可能已经登录,这就是 Principal 可用的原因。

当您访问应用程序 url 时,将调用 Spring Security Filter 链。

我建议您在常规 DAO 方法调用期间调用此方法。如果您已登录,则 Principal 应该可用。

@Repository
public class SomeDao


public String someDaoMethod() 
  getConnectedUser();
  ....

private String getConnectedUser( )  
    SecurityContext context = SecurityContextHolder.getContext();
    Authentication authentication = context.getAuthentication();
    if (authentication == null)
        return null;
    Object principal = authentication.getPrincipal();
    if (principal instanceof UserDetails) 
        return ((UserDetails) principal).getUsername();
     else 
        return principal.toString();
    

【讨论】:

谢谢兄弟,在我遵循您的想法(而不是代码)之后,它现在正在工作

以上是关于Spring security Principal 不适用于@PostConstruct的主要内容,如果未能解决你的问题,请参考以下文章

Spring security Principal 不适用于@PostConstruct

Spring Security - 使用 RouterFunction 的 Principal 始终为空

spring 在链接中使用 security:authentication principal.username

Spring Security OAuth2 JWT 资源服务器(旧版)具有 NULL Principal

如何在 Spring Security OAuth2 中使用 permitAll() 在公共页面上共享 User Principal/securityContext

如何使用 OAuth2 通过 Spring 获取自定义 Principal 对象?