Wiki source code of Create a Custom Authenticator

Last modified by Thomas Mortagne on 2023/04/28

Show last authors
1 It is possible to plug to any existing authentication mechanism by providing a bridge for it.
2
3 == Implement the authenticator ==
4
5 To implement a custom authentication the minimum is to implement the {{scm path="xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/user/api/XWikiAuthService.java"}}XWikiAuthService{{/scm}} interface. It's recommended to extend the {{scm path="xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java"}}XWikiAuthServiceImpl{{/scm}} class which is the default implementation(this is very useful if you want to reuse the standard login form, for example).
6
7 {{version since="13.3"}}
8 Your custom authentication should trigger a {{scm path="xwiki-platform-core/xwiki-platform-security/xwiki-platform-security-authentication/xwiki-platform-security-authentication-api/src/main/java/org/xwiki/security/authentication/UserAuthenticatedEvent.java"}}UserAuthenticatedEvent{{/scm}} when it implements itself ##checkAuth(XWikiContext context)## (if your authenticator is reusing the standard login form this part is handled by XWiki). You can find implementation examples in {{code}}xwiki-platform-oldcore{{/code}} as {{scm path="xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java"}}MyFormAuthenticator{{/scm}} and {{scm path="xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyBasicAuthenticator.java"}}MyBasicAuthenticator{{/scm}}. Note that a {{scm path="xwiki-platform-core/xwiki-platform-security/xwiki-platform-security-authentication/xwiki-platform-security-authentication-api/src/main/java/org/xwiki/security/authentication/UserAuthenticatedEvent.java"}}UserAuthenticatedEvent{{/scm}} should be created with a {{scm path="xwiki-platform-core/xwiki-platform-user/xwiki-platform-user-api/src/main/java/org/xwiki/user/UserReference.java"}}UserReference{{/scm}}.
9 {{/version}}
10
11 {{version since="15.3"}}
12 If you want your custom authenticator to be listed and selectable in the administration at runtime, you will need to expose it as a component with role `org.xwiki.security.authservice.XWikiAuthServiceComponent` and a unique hint. For existing authenticators adding this feature, a ##org.xwiki.security.authservice.AbstractXWikiAuthServiceWrapper## helper is provided which simply wrap your existing old style authenticator as a component.
13
14 Note that you don't need to upgrade your XWiki dependency to 15.3 in your authenticator for this, you can depend on [[org.xwiki.contrib:authservice-backport:1.1.1>>extensions:Extension.AuthServiceBackport||anchor="HHaveyourauthenticatorappearinAuthServiceApplicationafterit27sinstalled"]] (which supports XWiki 8.4+) instead.
15 {{/version}}
16
17 == Use your authenticator ==
18
19 Edit the //WEB-INF/xwiki.cfg// file and add a //xwiki.authentication.authclass// property pointing to your class. For example:
20
21 {{code language="properties"}}
22 xwiki.authentication.authclass = com.acme.MyCustomAuthenticationService
23 {{/code}}
24
25 == Example ==
26
27 Here is an example code for a custom authenticator:
28
29 {{code language="java"}}
30 package com.acme;
31
32 public class MyCustomAuthenticationService extends XWikiAuthServiceImpl
33 {
34 // We cannot use "real" component injection here because authenticators are not components currently
35 // But it's recommended to put most of your authenticator's actual code in a component (or several components) and use this component,
36 // it will make it a lot easier to reuse various XWiki tools and APIs
37 private MyCustomAuthentor authenticator = Utils.getComponent(MyCustomAuthenticator.class);
38
39 // If you don't plan to reuse the standard XWiki login you should implement this method which is usually in charge of gathering the user credentials
40 // or other means of indicating what is the current user (HTTP headers, etc.)
41 @Override
42 public XWikiUser checkAuth(XWikiContext context)
43 {
44 // Call the actual authenticator
45 return this.authenticator.checkAuth(context);
46 }
47
48 // This is the method which will be called if you reuse the standard means of gathering the credentials (login page, BASIC auth)
49 // What's left on your side is to validate the credential and create/update the XWiki user profile (and eventually synchronize other user-related info like the groups, etc.)
50 @Override
51 public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException
52 {
53 // Call the actual authenticator
54 return this.authenticator.checkAuth(context);
55 }
56 }
57
58 @Component(roles = MyCustomAuthenticator.class)
59 @Singleton
60 public MyCustomAuthenticator
61 {
62 @Inject
63 private ObservationManager observation;
64
65 public XWikiUser checkAuth(XWikiContext context)
66 {
67 // You authenticate a user somehow
68 ...
69
70 // 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
71 if (newAuth) {
72 // You have to retrieve its UserReference
73 // You should be able to use a UserReferenceResolver if needed
74 UserReference userReference = ...;
75
76 // Then, trigger a UserAuthenticatedEvent by passing previously retrieved user reference to UserAuthenticatedEvent constructor
77 this.observationManager.notify(new UserAuthenticatedEvent(userReference), null);
78 }
79 }
80
81 public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException
82 {
83 ...
84 }
85 }
86
87 @Component
88 @Singleton
89 @Named(MyCustomAuthService.ID)
90 public class MyCustomAuthService extends AbstractXWikiAuthServiceWrapper implements XWikiAuthServiceComponent
91 {
92 /**
93 * The identifier of the authenticator.
94 */
95 public static final String ID = "mycustom";
96
97 /**
98 * Wrap a {@link MyCustomAuthenticationService} instance.
99 */
100 public LDAPAuthService()
101 {
102 super(new MyCustomAuthenticationService());
103 }
104
105 @Override
106 public String getId()
107 {
108 return ID;
109 }
110 }
111
112 security.authservice.mycustom.name=My custom authenticator
113 security.authservice.mycustom.description=An example to show how to implement a custom authenticator
114 {{/code}}
115
116 You can find various authenticators examples in [[extensions>>http://extensions.xwiki.org/xwiki/bin/view/Main/WebHome#|t=extensions&p=1&l=30&s=doc.creationDate&d=desc&name=authenticator]] or [[sandbox>>https://github.com/xwiki-contrib/sandbox/tree/master/authenticators]].
117
118 Here's a [[tutorial on implementing a custom authentication class for authenticating against Oracle's SSO>>http://bodez.wordpress.com/2008/10/15/xwiki-user-authentication-with-oracle-sso/]].

Get Connected