1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.mylutece.modules.openid.authentication;
35
36 import fr.paris.lutece.plugins.mylutece.authentication.PortalAuthentication;
37 import fr.paris.lutece.plugins.mylutece.modules.openid.web.OpenIDApp;
38 import fr.paris.lutece.portal.service.security.LoginRedirectException;
39 import fr.paris.lutece.portal.service.security.LuteceUser;
40 import fr.paris.lutece.portal.service.security.SecurityService;
41 import fr.paris.lutece.portal.service.util.AppLogService;
42 import fr.paris.lutece.portal.service.util.AppPathService;
43 import fr.paris.lutece.portal.service.util.AppPropertiesService;
44 import fr.paris.lutece.util.url.UrlItem;
45
46 import org.apache.commons.lang.StringUtils;
47 import org.apache.log4j.Logger;
48
49 import org.openid4java.OpenIDException;
50
51 import org.openid4java.consumer.ConsumerException;
52 import org.openid4java.consumer.ConsumerManager;
53 import org.openid4java.consumer.VerificationResult;
54
55 import org.openid4java.discovery.DiscoveryInformation;
56 import org.openid4java.discovery.Identifier;
57
58 import org.openid4java.message.AuthRequest;
59 import org.openid4java.message.AuthSuccess;
60 import org.openid4java.message.ParameterList;
61 import org.openid4java.message.ax.AxMessage;
62 import org.openid4java.message.ax.FetchRequest;
63 import org.openid4java.message.ax.FetchResponse;
64 import org.openid4java.util.HttpClientFactory;
65 import org.openid4java.util.ProxyProperties;
66
67 import java.util.List;
68 import java.util.Set;
69
70 import javax.security.auth.login.LoginException;
71
72 import javax.servlet.http.HttpServletRequest;
73
74
75
76
77
78
79 public class OpenIDAuthentication extends PortalAuthentication
80 {
81
82
83 private static final String PROPERTY_AUTH_SERVICE_NAME = "mylutece-openid.service.name";
84 private static final String URL_CALLBACK = "jsp/site/plugins/mylutece/modules/openid/OpenIDProviderCallBack.jsp";
85 private static final String CONSTANT_PATH_ICON = "images/local/skin/plugins/mylutece/modules/openid/mylutece-openid.png";
86 private static final String ATTRIBUTE_FIRST_NAME = "firstname";
87 private static final String ATTRIBUTE_LAST_NAME = "lastname";
88 private static final String ATTRIBUTE_EMAIL = "email";
89 private static final String MESSAGE_KEY_AUTHENTICATION_FAILED = "module.mylutece.openid.authenticationFailed";
90 private static final String PLUGIN_NAME = "mylutece-openid";
91 private static final String PROPERTY_HTTPACCESS_PROXYHOST = "httpAccess.proxyHost";
92 private static final String PROPERTY_HTTPACCESS_PROXYPORT ="httpAccess.proxyPort";
93 private static final String PROPERTY_HTTPACCESS_PROXYUSERNAME ="httpAccess.proxyUserName";
94 private static final String PROPERTY_HTTPACCESS_PROXYPASSWORD ="httpAccess.proxyPassword";
95 private static final String PROPERTY_HTTPACCESS_DOMAINNAME ="httpaccess.domainName";
96
97 private static ConsumerManager _manager;
98 private static Logger _logger = Logger.getLogger( "openid" );
99
100
101
102
103 public OpenIDAuthentication( )
104 {
105 super( );
106
107
108 if ( _manager == null )
109 {
110 try
111 {
112
113
114
115 boolean bUsingProxy = false;
116 ProxyProperties properties = new ProxyProperties( );
117 String strProxyHost = AppPropertiesService.getProperty( PROPERTY_HTTPACCESS_PROXYHOST );
118 String strProxyPort = AppPropertiesService.getProperty( PROPERTY_HTTPACCESS_PROXYPORT );
119 String strProxyUserName = AppPropertiesService.getProperty( PROPERTY_HTTPACCESS_PROXYUSERNAME );
120 String strProxyPassword = AppPropertiesService.getProperty( PROPERTY_HTTPACCESS_PROXYPASSWORD );
121 String strDomainName = AppPropertiesService.getProperty( PROPERTY_HTTPACCESS_DOMAINNAME );
122
123 if ( StringUtils.isNotBlank( strProxyHost ) )
124 {
125 properties.setProxyHostName( strProxyHost );
126 bUsingProxy = true;
127 }
128 if ( StringUtils.isNotBlank( strProxyPassword ) )
129 {
130 properties.setPassword( strProxyPassword );
131 }
132
133
134 if ( StringUtils.isNotBlank( strProxyPort ) )
135 {
136 try
137 {
138 int nProxyPort = Integer.parseInt( strProxyPort );
139 properties.setProxyPort( nProxyPort );
140 }
141 catch ( NumberFormatException nfe )
142 {
143 AppLogService.error( "Error retrieving proxy port : " + strProxyHost );
144 }
145 }
146 if ( StringUtils.isNotBlank( strProxyUserName ) )
147 {
148 properties.setUserName( strProxyUserName );
149 }
150 if ( StringUtils.isNotBlank( strDomainName ) )
151 {
152 properties.setDomain( strDomainName );
153 }
154
155 if ( bUsingProxy )
156 {
157 HttpClientFactory.setProxyProperties( properties );
158 }
159 _manager = new ConsumerManager( );
160 }
161 catch ( ConsumerException e )
162 {
163 AppLogService.error( "Error instantiating OpenID ConsumerManager : " + e.getMessage( ), e );
164 }
165 }
166 }
167
168
169
170
171
172 public String getAuthServiceName( )
173 {
174 return AppPropertiesService.getProperty( PROPERTY_AUTH_SERVICE_NAME );
175 }
176
177
178
179
180
181
182 public String getAuthType( HttpServletRequest request )
183 {
184 return HttpServletRequest.BASIC_AUTH;
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198 public LuteceUser login( String strUserName, String strUserPassword, HttpServletRequest request )
199 throws LoginException, LoginRedirectException
200 {
201 String strRedirectUrl = getProviderRedirectUrl( request, strUserName );
202
203 if ( strRedirectUrl != null )
204 {
205 throw new LoginRedirectException( strRedirectUrl );
206 }
207
208 return null;
209 }
210
211
212
213
214
215 public void logout( LuteceUser user )
216 {
217 }
218
219
220
221
222
223
224 public LuteceUser getAnonymousUser( )
225 {
226 return new OpenIDUser( LuteceUser.ANONYMOUS_USERNAME, this );
227 }
228
229
230
231
232
233
234
235
236 public boolean isUserInRole( LuteceUser user, HttpServletRequest request, String strRole )
237 {
238
239 return false;
240 }
241
242
243
244
245
246
247
248 private String getProviderRedirectUrl( HttpServletRequest request, String strOpenID )
249 {
250 String strReturnUrl = getMessageUrl( request, MESSAGE_KEY_AUTHENTICATION_FAILED );
251
252 try
253 {
254
255 List discoveries = _manager.discover( strOpenID );
256
257
258
259 DiscoveryInformation discovered = _manager.associate( discoveries );
260
261
262 request.getSession( ).setAttribute( "openid-disc", discovered );
263
264
265 AuthRequest authReq = _manager.authenticate( discovered, getReturnUrl( request ) );
266
267
268 FetchRequest fetch = FetchRequest.createFetchRequest( );
269 fetch.addAttribute( ATTRIBUTE_FIRST_NAME, "http://schema.openid.net/namePerson/first", true );
270 fetch.addAttribute( ATTRIBUTE_LAST_NAME, "http://schema.openid.net/namePerson/last", true );
271 fetch.addAttribute( ATTRIBUTE_EMAIL, "http://schema.openid.net/contact/email", true );
272
273
274 authReq.addExtension( fetch );
275
276 strReturnUrl = authReq.getDestinationUrl( true );
277 }
278 catch ( OpenIDException e )
279 {
280 _logger.error( "OpenId Error building authentication request : " + e.getMessage( ), e );
281 }
282
283 return strReturnUrl;
284 }
285
286
287
288
289
290
291
292 private String getReturnUrl( HttpServletRequest request )
293 {
294 _logger.debug( "Callback URL : " + AppPathService.getBaseUrl( request ) + URL_CALLBACK );
295
296 return AppPathService.getBaseUrl( request ) + URL_CALLBACK;
297 }
298
299
300
301
302
303
304 public String verifyResponse( HttpServletRequest request )
305 {
306 String strReturnUrl = getMessageUrl( request, MESSAGE_KEY_AUTHENTICATION_FAILED );
307
308 _logger.debug( "Provider callback - host : " + request.getRemoteHost( ) + " - IP : " +
309 request.getRemoteAddr( ) );
310
311 OpenIDUser user = null;
312
313 try
314 {
315
316
317 ParameterList response = new ParameterList( request.getParameterMap( ) );
318
319
320 DiscoveryInformation discovered = (DiscoveryInformation) request.getSession( ).getAttribute( "openid-disc" );
321
322
323 StringBuffer receivingURL = request.getRequestURL( );
324 String queryString = request.getQueryString( );
325
326 if ( ( queryString != null ) && ( queryString.length( ) > 0 ) )
327 {
328 receivingURL.append( "?" ).append( request.getQueryString( ) );
329 }
330
331
332
333 VerificationResult verification = _manager.verify( receivingURL.toString( ), response, discovered );
334
335
336 Identifier verified = verification.getVerifiedId( );
337 _logger.debug( "Authentication verification : " + verified );
338
339 if ( verified != null )
340 {
341 user = new OpenIDUser( verified.getIdentifier( ), this );
342
343 AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse( );
344
345 if ( authSuccess.hasExtension( AxMessage.OPENID_NS_AX ) )
346 {
347 _logger.debug( "Authentication successfull - identifier : " + verified.getIdentifier( ) );
348
349 FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension( AxMessage.OPENID_NS_AX );
350
351 for ( String strKey : (Set<String>) fetchResp.getAttributes( ).keySet( ) )
352 {
353 _logger.debug( "Attribute " + strKey + " - value : " +
354 fetchResp.getAttributes( ).get( strKey ) );
355 }
356
357 String strFirstName = (String) fetchResp.getAttributes( ).get( ATTRIBUTE_FIRST_NAME );
358 String strLastName = (String) fetchResp.getAttributes( ).get( ATTRIBUTE_LAST_NAME );
359 List emails = fetchResp.getAttributeValues( ATTRIBUTE_EMAIL );
360 String email = (String) emails.get( 0 );
361
362 user.setUserInfo( LuteceUser.NAME_GIVEN, strFirstName );
363 user.setUserInfo( LuteceUser.NAME_FAMILY, strLastName );
364 user.setUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL, email );
365 }
366
367 SecurityService.getInstance( ).registerUser( request, user );
368
369 strReturnUrl = AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl( );
370 }
371 }
372 catch ( OpenIDException e )
373 {
374 _logger.error( "OpenId Error in provider response : " + e.getMessage( ), e );
375 }
376
377 return strReturnUrl;
378 }
379
380
381
382
383
384
385
386 private String getMessageUrl( HttpServletRequest request, String strMessageKey )
387 {
388 UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl( ) );
389 url.addParameter( OpenIDApp.PARAMETER_PAGE, OpenIDApp.PARAMETER_PAGE_VALUE );
390 url.addParameter( OpenIDApp.PARAMETER_ERROR, strMessageKey );
391
392 return url.getUrl( );
393 }
394
395
396
397
398
399 public String getIconUrl()
400 {
401 return CONSTANT_PATH_ICON;
402 }
403
404
405
406
407
408 public String getName()
409 {
410 return PLUGIN_NAME;
411 }
412
413
414
415
416
417 public String getPluginName()
418 {
419 return PLUGIN_NAME;
420 }
421
422
423
424
425
426 public boolean isMultiAuthenticationSupported()
427 {
428 return false;
429 }
430 }