Wiki source code of Create a Custom Authenticator
Version 5.1 by Thomas Mortagne on 2021/06/18
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | It is possible to plug to any existing authentication mechanism such as SiteMinder, etc. | ||
2 | |||
3 | To create a custom authentication do the following: | ||
4 | |||
5 | 1. 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 extends the {{scm path="xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthService.java"}}XWikiAuthServiceImpl{{/scm}} class which is a default implementation, this is very usefull if you want to reuse the standard login form for example). | ||
6 | 1. Edit the //WEB-INF/xwiki.cfg// file and add a //xwiki.authentication.authclass// property pointing to your class. For example: | ||
7 | |||
8 | {{code language="properties"}} | ||
9 | xwiki.authentication.authclass = com.acme.MyCustomAuthenticationService | ||
10 | {{/code}} | ||
11 | |||
12 | * {{version since="13.3RC1"}}To comply with latest best practices, 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 implement 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}}.{{/version}} | ||
13 | |||
14 | Here is an example code for a custom authenticator designed as a component: | ||
15 | |||
16 | {{code language="java"}} | ||
17 | public class MyCustomAuthenticationService extends XWikiAuthServiceImpl | ||
18 | { | ||
19 | // We cannot use use "real" component injection here because authenticators are not component currently | ||
20 | // But it's recommended to put most of your authenticator actual code in a component and use this component, | ||
21 | // it will make a lot easier to reuse various XWiki tools and APIs | ||
22 | private MyCustomAuthentor authenticator; | ||
23 | |||
24 | // 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 | ||
25 | // or other means of indicating what is the current user (HTTP headers, etc.) | ||
26 | @Override | ||
27 | public XWikiUser checkAuth(XWikiContext context) | ||
28 | { | ||
29 | // Call the actual authenticator | ||
30 | return this.authenticator.checkAuth(context); | ||
31 | } | ||
32 | |||
33 | // This is the method which will be called is you reuse the standard means of gathering of the credentials (login page, BASIC auth) | ||
34 | // 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.) | ||
35 | @Override | ||
36 | public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException | ||
37 | { | ||
38 | // Call the actual authenticator | ||
39 | return this.authenticator.checkAuth(context); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | @Component(roles = MyCustomAuthenticator.class) | ||
44 | @Singleton | ||
45 | public MyCustomAuthenticator | ||
46 | { | ||
47 | @Inject | ||
48 | private ObservationManager observation; | ||
49 | |||
50 | public XWikiUser checkAuth(XWikiContext context) | ||
51 | { | ||
52 | // You authenticate a user somehow | ||
53 | ... | ||
54 | |||
55 | // 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 | ||
56 | if (newAuth) { | ||
57 | // You have to retrieve its UserReference | ||
58 | // You should be able to use a UserReferenceResolver if needed | ||
59 | UserReference userReference = ...; | ||
60 | |||
61 | // Then, trigger a UserAuthenticatedEvent by passing previously retrieved user reference to UserAuthenticatedEvent constructor | ||
62 | this.observationManager.notify(new UserAuthenticatedEvent(userReference), null); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException | ||
67 | { | ||
68 | ... | ||
69 | } | ||
70 | } | ||
71 | {{/code}} | ||
72 | |||
73 | 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]]. | ||
74 | |||
75 | 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/]]. |