User Authentication

In some situations Togglz requires knowledge about the current user that is acting in the application. The two most important reasons for this are:

  • Features can be enabled only for specific users using the Username strategy.
  • Togglz needs to know which users should be allowed to use the Togglz Admin Console.

The strategy to obtain the current user is represented by the UserProvider interface. You can choose which strategy is used by implementing TogglzConfig.getUserProvider() like described in Configuration.

Togglz ships with a number of default implementations for integrating with different user management scenarios.

The following section will describe each of them in detail.

ServletUserProvider

This class is especially useful if your application is integrated with the authentication facilities of your container. It uses HttpServletRequest.getUserPrincipal() for obtaining the name of the current user and HttpServletRequest.isUserInRole() to check if the user is allowed to configure feature state using the admin console. You can optionally choose which role a user must have by specifying the group name in the constructor.

The the following implementation of TogglzConfig for an example:

public class MyTogglzConfiguration implements TogglzConfig {

    /* ..... */ 

    @Override
    public UserProvider getUserProvider() {
        return new ServletUserProvider("ADMIN_ROLE");
    }
}

SeamSecurityUserProvider

This provider implementation offers a very simple way to integrate Togglz with Seam Security. This provider can be used after adding the following dependency to your project:

<dependency>
  <groupId>org.togglz</groupId>
  <artifactId>togglz-seam-security</artifactId>
  <version>2.4.1.Final</version>
</dependency>

To use this provider, register it in your TogglzConfig like this:

public class MyTogglzConfiguration implements TogglzConfig {

    /* ..... */ 

    @Override
    public UserProvider getUserProvider() {
        return new SeamSecurityUserProvider();
    }
}

Now implement an authorizer method for @FeatureAdmin like this:

public class SeamSecurityAuthorizer {

    @Secures
    @FeatureAdmin
    public boolean isFeatureAdmin(Identity identity) {
        // return true if the current user is allowed to toggle features
    }
    
}

DeltaSpikeUserProvider

This provider offers integration with the Apache DeltaSpike Identity API. To use this provider, add the following dependency to your project:

<dependency>
  <groupId>org.togglz</groupId>
  <artifactId>togglz-deltaspike</artifactId>
  <version>2.4.1.Final</version>
</dependency>

Then change your TogglzConfig implementation to use the provider:

public class MyTogglzConfiguration implements TogglzConfig {

    /* ..... */ 

    @Override
    public UserProvider getUserProvider() {
        return new DeltaSpikeUserProvider();
    }
}

Please note that the provider currently doesn't support to set the feature admin flag for a user. This is because the DeltaSpike API for authorization isn't stable yet. So if you want to set the flag using some custom criterion, you can extend DeltaSpikeUserProvider and overwrite the isFeatureAdmin(Identity) method.

SpringSecurityUserProvider

This implementation provides a way to integrate Togglz with Spring Security. To use this provider you have to add the following dependency to your project.

<dependency>
  <groupId>org.togglz</groupId>
  <artifactId>togglz-spring-security</artifactId>
  <version>2.4.1.Final</version>
</dependency>

To configure Togglz to use this provider, add it to your TogglzConfig. Please note that you have to specify an authority name in the constructor of the class. Users with this authority will automatically be able to perform Togglz administration tasks.

public class MyTogglzConfiguration implements TogglzConfig {

    /* ..... */ 

    @Override
    public UserProvider getUserProvider() {
        return new SpringSecurityUserProvider("ADMIN_AUTHORITY");
    }
}

ThreadLocalUserProvider

Many applications are using servlet filters to implement authentication. In these scenarios authentication is typically done for a single request received by the application. If you are using such a pattern for user authentication you can use ThreadLocalUserProvider to tell Togglz about the current user.

This implementation allows to store the current user in a ThreadLocal object for the current request. The only thing you have to do is to set the current user from your filter like this:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {

    String username = ...;
    boolean isAdmin = ...;

    FeatureUser user = new SimpleFeatureUser(username, isAdmin);

    ThreadLocalUserProvider.bind(user);
    try {
        chain.doFilter(request, response);
    } finally {
        ThreadLocalUserProvider.release();
    }

}

Then register the ThreadLocalUserProvider in your TogglzConfig like this:

public class MyTogglzConfiguration implements TogglzConfig {

    /* ..... */ 

    @Override
    public UserProvider getUserProvider() {
        return new ThreadLocalUserProvider();
    }
}

Custom Implementation

If none of the default implementations fits you needs, you can always think about implementing a provider yourself. This is very easy. You just have to implement a single method called getCurrentUser().

The following example shows an implementation which reads the username from a servlet request attribute:

public class MyTogglzConfiguration implements TogglzConfig {

    /* ..... */ 

    @Override
    public UserProvider getUserProvider() {
        return new UserProvider() {
            
            @Override
            public FeatureUser getCurrentUser() {
            
                HttpServletRequest request = HttpServletRequestHolder.get();
                
                String username = (String) request.getAttribute("username");
                boolean isAdmin = "admin".equals(username);
                
                return new SimpleFeatureUser(username, isAdmin);
                
            }
        };
    }
}

Please note the HttpServletRequestHolder class which may be very useful if you are implementing a UserProvider yourself because it allows to obtain the HttpServletRequest from anywhere in your application.