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.oauth2.service;
35
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.Map;
42 import java.util.Map.Entry;
43
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
46
47 import org.apache.commons.lang3.StringUtils;
48 import org.apache.log4j.Logger;
49
50 import fr.paris.lutece.plugins.mylutece.authentication.MultiLuteceAuthentication;
51 import fr.paris.lutece.plugins.mylutece.business.LuteceUserAttributeDescription;
52 import fr.paris.lutece.plugins.mylutece.modules.oauth2.authentication.Oauth2Authentication;
53 import fr.paris.lutece.plugins.mylutece.modules.oauth2.authentication.Oauth2User;
54 import fr.paris.lutece.plugins.mylutece.service.MyLuteceUserService;
55 import fr.paris.lutece.plugins.mylutece.web.MyLuteceApp;
56 import fr.paris.lutece.plugins.oauth2.business.Token;
57 import fr.paris.lutece.portal.service.security.LuteceUser;
58 import fr.paris.lutece.portal.service.security.SecurityService;
59 import fr.paris.lutece.portal.service.spring.SpringContextService;
60 import fr.paris.lutece.portal.service.util.AppLogService;
61 import fr.paris.lutece.portal.service.util.AppPropertiesService;
62 import fr.paris.lutece.portal.web.PortalJspBean;
63
64
65
66
67
68 public final class Oauth2Service
69 {
70
71
72 private static Oauth2Authentication _authService ;
73
74
75 private static Logger _logger = Logger.getLogger( "lutece.oauth2" );
76
77
78 private static final String AUTHENTICATION_BEAN_NAME = "mylutece-oauth2.authentication";
79
80
81 private static final String PROPERTY_USER_KEY_NAME = "mylutece-oauth2.attributeKeyUsername";
82
83
84 private static final String PROPERTY_USER_MAPPING_ATTRIBUTES = "mylutece-oauth2.userMappingAttributes";
85
86
87 private static final String PROPERTY_IDENTITY_ATTRIBUTE_KEY = "mylutece-oauth2.attributeIdentityKey";
88
89
90 private static final String TOKEN_SUBJECT = "sub";
91
92
93 private static final String CONSTANT_LUTECE_USER_PROPERTIES_PATH = "mylutece-oauth2.attribute";
94
95
96 private static Map<String, List<String>> ATTRIBUTE_USER_MAPPING;
97
98
99 private static String [ ] ATTRIBUTE_USER_KEY_NAME;
100
101
102 private static final String SEPARATOR = ",";
103
104
105 private static Oauth2Service _singleton;
106
107
108
109
110 private Oauth2Service( )
111 {
112 }
113
114
115
116
117
118
119 public static Oauth2Service getInstance( )
120 {
121 if ( _singleton == null )
122 {
123
124 _singleton = new Oauth2Service( );
125 String strTabUserKey = AppPropertiesService.getProperty( PROPERTY_USER_KEY_NAME );
126 if ( StringUtils.isNotBlank( strTabUserKey ) )
127 {
128 ATTRIBUTE_USER_KEY_NAME = strTabUserKey.split( SEPARATOR );
129 }
130 String strUserMappingAttributes = AppPropertiesService.getProperty( PROPERTY_USER_MAPPING_ATTRIBUTES );
131 ATTRIBUTE_USER_MAPPING = new HashMap<String, List<String>>( );
132
133 if ( StringUtils.isNotBlank( strUserMappingAttributes ) )
134 {
135 String [ ] tabUserProperties = strUserMappingAttributes.split( SEPARATOR );
136 String [ ] tabPropertiesValues;
137 String userProperties;
138
139 for ( int i = 0; i < tabUserProperties.length; i++ )
140 {
141 userProperties = AppPropertiesService.getProperty( CONSTANT_LUTECE_USER_PROPERTIES_PATH + "." + tabUserProperties [i] );
142
143 if ( StringUtils.isNotBlank( userProperties ) )
144 {
145
146 if ( userProperties.contains( SEPARATOR ) )
147 {
148 tabPropertiesValues = userProperties.split( SEPARATOR );
149
150 for ( int n = 0; i < tabPropertiesValues.length; n++ )
151 {
152 if ( !ATTRIBUTE_USER_MAPPING.containsKey( tabPropertiesValues [n] ) )
153 {
154 ATTRIBUTE_USER_MAPPING.put( tabPropertiesValues [n], new ArrayList<String>( ) );
155 }
156 ATTRIBUTE_USER_MAPPING.get( tabPropertiesValues [n] ).add( tabUserProperties [i] );
157 }
158
159 }
160 else
161 {
162
163 if ( !ATTRIBUTE_USER_MAPPING.containsKey( userProperties ) )
164 {
165 ATTRIBUTE_USER_MAPPING.put( userProperties, new ArrayList<String>( ) );
166 }
167 ATTRIBUTE_USER_MAPPING.get( userProperties ).add( tabUserProperties [i] );
168 }
169
170 }
171 }
172 }
173 }
174
175 return _singleton;
176 }
177
178
179
180
181
182
183
184
185
186
187
188
189 public Oauth2User processAuthentication( HttpServletRequest request, Map<String, Object> mapUserInfo, Token token )
190 {
191
192
193 if ( token.getIdToken( ) != null && token.getIdToken( ).getSubject( ) != null )
194 {
195 mapUserInfo.put( TOKEN_SUBJECT, token.getIdToken( ).getSubject( ) );
196
197 }
198 Oauth2User user = null;
199 for ( int i = 0; i < ATTRIBUTE_USER_KEY_NAME.length; i++ )
200 {
201
202 if ( mapUserInfo.containsKey( ATTRIBUTE_USER_KEY_NAME [i] ) )
203 {
204 user = new Oauth2User( (String) mapUserInfo.get( ATTRIBUTE_USER_KEY_NAME [i] ), token, _authService );
205 }
206 }
207
208 if ( user != null )
209 {
210
211 for ( Entry<String, Object> entry : mapUserInfo.entrySet( ) )
212 {
213 if ( ATTRIBUTE_USER_MAPPING.containsKey( entry.getKey( ) ) )
214 {
215 for ( String strUserInfo : ATTRIBUTE_USER_MAPPING.get( entry.getKey( ) ) )
216 {
217
218 Object val = entry.getValue( );
219 if ( val instanceof ArrayList<?> )
220 {
221
222 StringBuffer strBufVal = new StringBuffer( );
223 for ( String tabVal : (ArrayList<String>) val )
224 {
225 strBufVal.append( tabVal );
226 strBufVal.append( SEPARATOR );
227 }
228 if ( strBufVal.length( ) > 0 )
229 {
230 user.setUserInfo( strUserInfo, strBufVal.substring( 0, strBufVal.length( ) - 1 ) );
231 }
232
233 user.setUserInfo( strUserInfo, strBufVal.toString( ) );
234
235 }
236 else
237 {
238 user.setUserInfo( strUserInfo, (String) val );
239
240 }
241 }
242 }
243
244 if ( !StringUtils.isEmpty( user.getUserInfo( LuteceUser.HOME_INFO_ONLINE_EMAIL ) ) )
245 {
246 user.setEmail( user.getUserInfo( LuteceUser.HOME_INFO_ONLINE_EMAIL ) );
247
248 }
249 else
250 if ( !StringUtils.isEmpty( user.getUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL ) ) )
251 {
252 user.setEmail( user.getUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL ) );
253
254 }
255
256 }
257
258
259
260 String strIdentityKey = user.getName( );
261 String strIdentityKeyAttribute = AppPropertiesService.getProperty( PROPERTY_IDENTITY_ATTRIBUTE_KEY );
262 if ( strIdentityKeyAttribute != null && mapUserInfo.containsKey( strIdentityKeyAttribute ) )
263 {
264 strIdentityKey = mapUserInfo.get( strIdentityKeyAttribute ).toString( );
265 }
266
267 user.setName( strIdentityKey );
268 MyLuteceUserService.provideUserExternalInfos( user );
269
270
271 Oauth2LuteceUserSessionService.getInstance( ).addLuteceUserSession( user.getName( ), request.getSession( true ).getId( ) );
272
273 }
274
275 SecurityService.getInstance( ).registerUser( request, user );
276
277 return user;
278 }
279
280
281
282
283 public void init()
284 {
285
286
287 _authService = SpringContextService.getBean( AUTHENTICATION_BEAN_NAME );
288
289 if ( _authService != null )
290 {
291 MultiLuteceAuthentication.registerAuthentication( _authService );
292 }
293 else
294 {
295 AppLogService.error( "Mylutece Ouath2 Authentication not found, please check your mylutece-oauth2_context.xml configuration" );
296 }
297
298 }
299
300
301
302
303
304 public List<LuteceUserAttributeDescription> getLuteceUserAttributesProvided(Locale locale)
305 {
306
307 List<LuteceUserAttributeDescription> listUserDescription= new ArrayList<LuteceUserAttributeDescription>();
308
309
310 String strUserMappingAttributes = AppPropertiesService.getProperty( PROPERTY_USER_MAPPING_ATTRIBUTES );
311 ATTRIBUTE_USER_MAPPING = new HashMap<String, List<String>>( );
312
313 if ( StringUtils.isNotBlank( strUserMappingAttributes ) )
314 {
315 String [ ] tabUserProperties = strUserMappingAttributes.split( SEPARATOR );
316
317 for ( int i = 0; i < tabUserProperties.length; i++ )
318 {
319
320 listUserDescription.add(new LuteceUserAttributeDescription( tabUserProperties [i], AppPropertiesService.getProperty( CONSTANT_LUTECE_USER_PROPERTIES_PATH + "." + tabUserProperties [i] ) , ""));
321 }
322 }
323
324
325 return listUserDescription;
326 }
327
328
329
330
331
332
333
334 public static void processLogout( HttpServletRequest request )
335 {
336 _logger.debug( "Process logout" );
337 SecurityService.getInstance( ).logoutUser( request );
338 }
339
340
341
342
343
344
345
346
347
348
349
350 public static void redirect( HttpServletRequest request, HttpServletResponse response ) throws IOException
351 {
352 String strNextURL = PortalJspBean.getLoginNextUrl( request );
353 _logger.info( "Next URL : " + strNextURL );
354
355 if ( strNextURL == null )
356 {
357 strNextURL = MyLuteceApp.getDefaultRedirectUrl( );
358 }
359
360 strNextURL = response.encodeRedirectURL( strNextURL );
361
362 response.sendRedirect( strNextURL );
363 }
364
365
366
367
368
369
370 }