Define auditor aware principal (#2654)
Allowing for cusomising auditor by extenders Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware.AuditorAwarePrincipal;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
@@ -140,11 +141,11 @@ public interface SecurityContextSerializer {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String principal;
|
||||
private String[] authorities;
|
||||
private boolean authenticated;
|
||||
private String tenant;
|
||||
private boolean controller;
|
||||
private String auditor;
|
||||
private String[] authorities;
|
||||
private boolean authenticated;
|
||||
|
||||
SecCtxInfo(final SecurityContext securityContext) {
|
||||
final Authentication authentication = securityContext.getAuthentication();
|
||||
@@ -158,7 +159,7 @@ public interface SecurityContextSerializer {
|
||||
// keep the auditor, ofr audit purposes,
|
||||
// sets principal to the resolved auditor and then deserialized authentication will return it as principal
|
||||
// since the class is not known to auditor aware - it shall used default - principal as auditor
|
||||
principal = SpringSecurityAuditorAware.resolveAuditor(authentication);
|
||||
auditor = SpringSecurityAuditorAware.resolveAuditor(authentication);
|
||||
authorities = authentication.getAuthorities().stream().map(Object::toString).toArray(String[]::new);
|
||||
authenticated = authentication.isAuthenticated();
|
||||
}
|
||||
@@ -166,6 +167,7 @@ public interface SecurityContextSerializer {
|
||||
private SecurityContext toSecurityContext() {
|
||||
final SecurityContext ctx = SecurityContextHolder.createEmptyContext();
|
||||
final Object details = tenant == null ? null : new TenantAwareAuthenticationDetails(tenant, controller);
|
||||
final AuditorAwarePrincipal principal = () -> auditor;
|
||||
final Collection<? extends GrantedAuthority> grantedAuthorities =
|
||||
Stream.of(authorities).map(SimpleGrantedAuthority::new).toList();
|
||||
ctx.setAuthentication(new Authentication() {
|
||||
@@ -202,7 +204,7 @@ public interface SecurityContextSerializer {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return principal;
|
||||
return auditor;
|
||||
}
|
||||
});
|
||||
return ctx;
|
||||
|
||||
@@ -63,16 +63,25 @@ public class SpringSecurityAuditorAware implements AuditorAware<String> {
|
||||
if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails && tenantAwareDetails.controller()) {
|
||||
return "CONTROLLER_PLUG_AND_PLAY";
|
||||
}
|
||||
if (authentication.getPrincipal() instanceof UserDetails userDetails) {
|
||||
final Object principal = authentication.getPrincipal();
|
||||
if (principal instanceof AuditorAwarePrincipal auditorAwarePrincipal) {
|
||||
return auditorAwarePrincipal.getAuditor();
|
||||
}
|
||||
if (principal instanceof UserDetails userDetails) {
|
||||
return userDetails.getUsername();
|
||||
}
|
||||
if (authentication.getPrincipal() instanceof OidcUser oidcUser) {
|
||||
if (principal instanceof OidcUser oidcUser) {
|
||||
return oidcUser.getPreferredUsername();
|
||||
}
|
||||
return authentication.getPrincipal().toString();
|
||||
return principal.toString();
|
||||
}
|
||||
|
||||
private static boolean isAuthenticationInvalid(final Authentication authentication) {
|
||||
return authentication == null || !authentication.isAuthenticated() || authentication.getPrincipal() == null;
|
||||
}
|
||||
|
||||
public interface AuditorAwarePrincipal {
|
||||
|
||||
String getAuditor();
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class SecurityContextSerializerTest {
|
||||
final String serialized = JSON_SERIALIZATION.serialize(securityContext);
|
||||
final SecurityContext deserialized = JSON_SERIALIZATION.deserialize(serialized);
|
||||
final Authentication authentication = deserialized.getAuthentication();
|
||||
assertThat(authentication.getPrincipal()).hasToString("user");
|
||||
assertThat(SpringSecurityAuditorAware.resolveAuditor(authentication)).hasToString("user");
|
||||
assertThat(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).toList()).isEqualTo(AUTHORITIES);
|
||||
assertThat(authentication.isAuthenticated()).isTrue();
|
||||
assertThat(authentication.getDetails()).isEqualTo(details);
|
||||
@@ -76,7 +76,7 @@ class SecurityContextSerializerTest {
|
||||
assertThat(oldSerialized).isNotEqualTo(newSerialized);
|
||||
final Authentication deserializedOld = JSON_SERIALIZATION.deserialize(oldSerialized).getAuthentication();
|
||||
final Authentication deserializedNew = JSON_SERIALIZATION.deserialize(newSerialized).getAuthentication();
|
||||
assertThat(deserializedOld.getPrincipal()).hasToString(deserializedNew.getPrincipal().toString());
|
||||
assertThat(SpringSecurityAuditorAware.resolveAuditor(deserializedOld)).hasToString(SpringSecurityAuditorAware.resolveAuditor(deserializedNew));
|
||||
assertThat(deserializedOld.getAuthorities()).isEqualTo(deserializedNew.getAuthorities());
|
||||
assertThat(deserializedOld.isAuthenticated()).isEqualTo(deserializedNew.isAuthenticated());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user