Create a Custom Authenticator

Version 5.1 by Thomas Mortagne on 2021/06/18

It is possible to plug to any existing authentication mechanism such as SiteMinder, etc.

To create a custom authentication do the following:

  1. Implement the XWikiAuthService interface. It's recommended to extends the XWikiAuthServiceImpl class which is a default implementation, this is very usefull if you want to reuse the standard login form for example).
  2. Edit the WEB-INF/xwiki.cfg file and add a xwiki.authentication.authclass property pointing to your class. For example:
xwiki.authentication.authclass = com.acme.MyCustomAuthenticationService

Here is an example code for a custom authenticator designed as a component:

public class MyCustomAuthenticationService extends XWikiAuthServiceImpl
{
   // We cannot use use "real" component injection here because authenticators are not component currently
   // But it's recommended to put most of your authenticator actual code in a component and use this component,
   // it will make a lot easier to reuse various XWiki tools and APIs
   private MyCustomAuthentor authenticator;

   // If you don't plan to reuse the standard XWiki login you should implement this method which is usually in charge or gathering the user credentials
   // or other means of indicating what is the current user (HTTP headers, etc.)
   @Override
   public XWikiUser checkAuth(XWikiContext context)
   {
       // Call the actual authenticator
       return this.authenticator.checkAuth(context);
   }

   // This is the method which will be called is you reuse the standard means of gathering of the credentials (login page, BASIC auth)
   // What's left on your side if to validate the credential and create/update the XWiki user profile (and eventually synchronize other user related info like the groups, etc.)
   @Override
   public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException
   {
       // Call the actual authenticator
       return this.authenticator.checkAuth(context);
   }
}

@Component(roles = MyCustomAuthenticator.class)
@Singleton
public MyCustomAuthenticator
{
   @Inject
   private ObservationManager observation;

   public XWikiUser checkAuth(XWikiContext context)
   {
       // You authenticate a user somehow
       ...

       // Since 13.3, if this is a new authentication (the user was not already authenticated in this session) you should send a notification about that
       if (newAuth) {
         // You have to retrieve its UserReference
         // You should be able to use a UserReferenceResolver if needed
         UserReference userReference = ...;

         // Then, trigger a UserAuthenticatedEvent by passing previously retrieved user reference to UserAuthenticatedEvent constructor
         this.observationManager.notify(new UserAuthenticatedEvent(userReference), null);
       }
   }

 public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException
 {
   ...
 }
}

You can find various authenticators examples in extensions or sandbox.

Here's a tutorial on implementing a custom authentication class for authenticating against Oracle's SSO.

Get Connected