我有许多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。为什么是这样?在这样的申请中访问当前委托人的首选方法是什么?请注意,此代码需要驻留在Controller类之外。
我猜测@Preauthorize注释背后的代码必须以某种方式访问此Principal以确定它们是否具有相应的角色?
您可以使用EventListener
获得成功:AuthorizedEvent
或失败AuthorizationFailureEvent
@EventListener(value = {AuthorizedEvent.class})
public void onApplicationEvent(AuthorizedEvent event) {
log.info("Authorization : {}", event.getAuthentication().getName());
}