如何在使用Redis会话存储的Spring Boot应用中获取当前主体

时间:2018-09-17 19:52:07

标签: spring spring-boot redis saml-2.0 spring-session

我有许多Spring Boot(版本1.5.3)微服务应用程序都共享Redis会话存储。我对类路径具有以下依赖关系,并且用户能够登录并将其会话存储在Redis中:

<dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

每个微服务中的控制器端点都使用@Preauthorize批注,以确保当前用户具有适当的授予权限来调用端点。这些注解确实可以确保只有具有正确角色的那些用户才能调用,因此安全性似乎设置正确。但是,我还需要将尝试调用端点的用户名输出到审核日志。为此,我有以下方法应将用户名作为字符串返回:

private String userDetailsString() {
    StringBuilder buf = new StringBuilder();
    SecurityContext context = getSecurityContext();
    Authentication authentication = context.getAuthentication();
    if(authentication != null) {
        UserDetails principal = (UserDetails)authentication.getPrincipal();
        buf.append("Requested by: ");
        buf.append(principal.getUsername());
    } else {
        buf.append("Requested by: null");
    }
    return buf.toString();
}

protected SecurityContext getSecurityContext() {
    return SecurityContextHolder.getContext();
}

但是,Authentication对象始终为null。为什么是这样?在这样的应用程序中访问当前Principal的首选方法是什么?请注意,此代码需要驻留在Controller类之外。

我猜想@Preauthorize批注后面的代码必须以某种方式访问​​此Principal以确定它们是否具有适当的角色?

1 个答案:

答案 0 :(得分:1)

您可以使用EventListener获得成功:AuthorizedEvent或失败AuthorizationFailureEvent

@EventListener(value = {AuthorizedEvent.class})
public void onApplicationEvent(AuthorizedEvent event) {
   log.info("Authorization : {}", event.getAuthentication().getName());
}