You are viewing the documentation for Blueriq 17. Documentation for other versions is available in our documentation directory.

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Blueriq provides AuthenticationMapper interface that should be implementation when a CustomBean authentication provider is used and the authentication provider returns a custom Authentication implementation. Default implementations are already provided by Blueriq for the following Authentication implementations:

  • UsernamePasswordAuthenticationToken
  • AnonymousAuthenticationToken


To implementation a custom AuthenticationMapper  the following has to be done:

  • Add the blueriq-component-api to the project dependencies.
pom.xml
<project ...>
  ...  
  <dependencies>
    ...
    <dependency>
	  <groupId>com.blueriq</groupId>
	  <artifactId>blueriq-component-api</artifactId>
	  <version>${blueriq.version}</version>
    </dependency>
    ...
  </dependencies>
  ...
</project>
  • Define the custom implementation like below:
CustomExternalFlowStore.java
package ...;

import com.blueriq.component.api.externalflow.data.mapping.AuthenticationMapper;
// other imports ...

@Component
public class CustomAuthenticationMapper implements AuthenticationMapper {

  @Override
  public String authenticationType() {
    // add implementation here
    return null;
  }

  @Override
  public boolean supportsContract(ContractVersion contractVersion) {
    // add implementation here
    return false;
  }

  @Override
  public boolean canMap(Authentication authentication) {
    // add implementation here
    return false;
  }

  @Override
  public void fillModel(ObjectModelCreation objectModel, Authentication authentication) {
    // add implementation here
  }

  @Override
  public Authentication toAuthentication(ObjectModelRetrieval objectModel) {
    // add implementation here
    return null;
  }
}

Example CustomBlueriqAuthentication AuthenticationMapper

Here is an example implementation of the authentication mapper for a custom BlueriqAuthentication implementation. This implementation has an additional token field.

The CustomBlueriqAuthentication

CustomBlueriqAuthentcation
public class CustomBlueriqAuthentication implements BlueriqAuthentication {

  private final String username;
  private final String token;
  private final List<String> teams;
  private final List<String> roles;
  private final List<? extends GrantedAuthority> authorities;
  private final Map<String, List<String>> claims;
  private final boolean authenticated;

  public CustomBlueriqAuthentication(String username, String token, List<String> teams, List<String> roles,
      Map<String, List<String>> claims, boolean authenticated) {
    this.username = username;
    this.token = token;
    this.teams = teams;
    this.roles = roles;
    this.authorities = roles.stream().map(SimpleGrantedAuthority::new).toList();
    this.claims = claims;
    this.authenticated = authenticated;
  }

  @Override
  public List<String> getTeams() {
    return teams;
  }

  @Override
  public List<String> getRoles() {
    return roles;
  }

  @Override
  public boolean isAnonymous() {
    return false;
  }

  @Override
  public boolean isAutomatic() {
    return false;
  }

  @Override
  public Set<String> getClaimNames() {
    return claims.keySet();
  }

  @Override
  public List<String> getClaim(String name) {
    return claims.get(name);
  }

  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    return authorities;
  }

  @Override
  public Object getCredentials() {
    return null;
  }

  @Override
  public Object getDetails() {
    return null;
  }

  @Override
  public Object getPrincipal() {
    return username;
  }

  @Override
  public boolean isAuthenticated() {
    return authenticated;
  }

  @Override
  public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
    throw new IllegalArgumentException("Cannot set authenticated after construction");
  }

  @Override
  public String getName() {
    return username;
  }

  public String getToken() {
    return token;
  }
}

Adding the dependencies

The following dependencies are required in the pom.xml

pom.xml
<project ...>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>com.blueriq</groupId>
      <artifactId>blueriq-component-api</artifactId>
      <version>${blueriq.version}</version>
    </dependency>
    ...
  <dependencies>
  ...
</project>

Implementing the AuthenticationMapper Interface

Please make sure that CustomBlueriqAuthenticationMapper component is scanned by Spring.

HazelcastExternalFlowStore.java
package ...;

import com.blueriq.component.api.externalflow.data.mapping.AuthenticationMapper;
// other imports ...

@Component
public class CustomAuthenticationMapper implements AuthenticationMapper {

  @Override
  public String authenticationType() {
    // provide a unique authentication type identifier that will be used to identity which mapper should be used.
    return "custom-blueriq-token-authentication";
  }

  @Override
  public boolean supportsContract(ContractVersion contractVersion) {
    // check if the AuthenticationMapper supports writing and reading for the incoming contract version.
    return SupportedContractVersions.V_1_0.equals(contractVersion);
  }

  @Override
  public boolean canMap(Authentication authentication) {
    // check if the provided authentication is supported by the AuthenticationMapper
    return authentication instanceof CustomBlueriqAuthentication;
  }

  @Override
  public void fillModel(ObjectModelCreation objectModel, Authentication authentication) {
    // verify that we still have the supported Authentication object.
    if (!(authentication instanceof CustomBlueriqAuthentication)) {
      throw new IllegalArgumentException(
          "Unable to fill authentication model, unexpected authentication implementation: "
              + authentication.getClass().getSimpleName());
    }

    CustomBlueriqAuthentication customAuthentication = (CustomBlueriqAuthentication) authentication;

    // We need to supply the objectModel with enough information that it is able to the reconstruct the
    // CustomBlueriqAuthentication object in the toAuthentication method.
    objectModel.put("token", customAuthentication.getToken());
    objectModel.put("user", customAuthentication.getName());
    objectModel.put("authenticated", customAuthentication.isAuthenticated());

    ObjectModelCreation claims = objectModel.createObject("claims");
    customAuthentication.getClaimNames().forEach(key -> {
      ArrayModelCreation values = claims.createArray(key);
      customAuthentication.getClaim(key).forEach(values::add);
    });

    ArrayModelCreation roles = objectModel.createArray("roles");
    customAuthentication.getRoles().forEach(roles::add);

    ArrayModelCreation teams = objectModel.createArray("teams");
    customAuthentication.getTeams().forEach(teams::add);
  }

  @Override
  public Authentication toAuthentication(ObjectModelRetrieval objectModel) {
    // We retrieve all of the filled information from the objectModel, in order to recreate the
    // CustomBlueriqAuthentication

    String token = objectModel.getString("token");
    String user = objectModel.getString("user");
    boolean isAuthenticated = objectModel.getBoolean("authenticated");

    List<String> roles = objectModel.getStringList("roles");
    List<String> teams = objectModel.getStringList("teams");

    ObjectModelRetrieval claimsModel = objectModel.getObject("claims");
    Map<String, List<String>> claims =
        claimsModel.getProperties().collect(Collectors.toMap(Function.identity(), claimsModel::getStringList));

    return new CustomBlueriqAuthentication(user, token, teams, roles, claims, isAuthenticated);
  }
}



  • No labels