// this is embedded in blog post https://phip1611.de/?p=9898
/*
Copyright 2018 Philipp Schuster
Web: phip1611.de
Twitter: @phip1611
*/
package de.phips_photoblog.service.impl.auth.token;
import de.phips_photoblog.controller.dto.UserDto;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.UUID;
import java.util.logging.Logger;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
/**
* Authentication Token used for my UUID-like token thing. Each request to /admin has a
* "X-Token"-Header. This token-mechanism is represented with this class. It holds
* the token and the principal.
*
* This class is instantiated by the TokenFilter and will be introduced to spring
* security as active Authentication.
*
* Implementations which use this class should be immutable. (Spring Doc)
*/
public class TokenAuthentication extends AbstractAuthenticationToken {
private static final Logger LOGGER = Logger.getLogger("Auth");
private final UUID secretToken;
private final UserDto userDto;
public TokenAuthentication(UUID secretToken) {
super(emptyList());
this.secretToken = secretToken;
this.userDto = null;
// this.setAuthenticated(false); default value from super class
// because this is set to false an AuthProvider known to spring security
// will verify this authentication object!
}
public TokenAuthentication(UUID secretToken, UserDto userDto) {
super(userDto.getRoles().stream().map(SimpleGrantedAuthority::new).collect(toList()));
this.secretToken = secretToken;
this.userDto = userDto;
// this.setAuthenticated(false); // this.setAuthenticated(false); default value from super class
// because this is set to false an AuthProvider known to spring security
// will verify this authentication object!
}
/**
* Enriches a TokenAuthentication with the principle. This should be used after the
* authentication provider verified that the TokenAuthentication is valid. Then it
* creates a new instance enriched with the principle/UserDto. It's done like that
* to fulfill the Immutable contract by the super class.
* @param principal UserDto
* @return enriched object as new instance
*/
public TokenAuthentication enrichWithPrincipal(UserDto principal) {
TokenAuthentication token = new TokenAuthentication(this.secretToken, principal);
token.setAuthenticated(true); // we do this here because enrichWithPrincipal() will only
// be called in the AuthenticationProvider which will invoke this method if
// the token was validated
return token;
}
@Override
public Object getCredentials() {
return this.secretToken;
}
@Override
public Object getPrincipal() {
return this.userDto;
}
@Override
public String getName() {
return this.userDto.getUsername();
}
}