我有许多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以确定它们是否具有适当的角色?
答案 0 :(得分:1)
您可以使用EventListener
获得成功:AuthorizedEvent
或失败AuthorizationFailureEvent
@EventListener(value = {AuthorizedEvent.class})
public void onApplicationEvent(AuthorizedEvent event) {
log.info("Authorization : {}", event.getAuthentication().getName());
}