Feature #360
closedOpenAM - authentication endpoint
Added by Marcel Poul over 7 years ago. Updated over 7 years ago.
100%
Description
IdM will be able to authenticate users against openAM. The aim of this ticket is to write down functional specification and design of openAM authentication method.
Moreover, the authorisation of the user may be in scope too - the token given by openAM can store authorisation data like group membership. Sometimes the openAM is managed by IdM itself, so the authorisation check may be done against roles in IdM, but it is not as general solution as openAM authorisation.
Related issues
Updated by Peter Štrunc over 7 years ago
OpenAM authentication module will consist of two main parts.
- Authentication filter in filter chain
- REST endpoint providing info about users privileges in OpenAM
First part is pretty straightforward and basically consists of creating OpenAMAuthenticationFilter and OpenAMAuthenticationManager classes and inserting them in spring's security filter chain. Actual OpenAM endpoint's URL will be stored in IdM's configuration.
Said REST endpoint will work as proxy between OpenAM and user and will basically provide access to identity attributes from OpenAM.
TODOS:- Should this feature be part of core IdM or should it be developed as a separate module?
- Which configuration parameters will be needed? (Name of the cookie, OpenAM URL, domain for the cookie, which OpenAM identity's attributes will be exposed via IdM's REST endpoint)
Updated by Peter Štrunc over 7 years ago
- Assignee changed from Peter Štrunc to Radek Tomiška
- OpenAmAuthenticationManager - the aim of this class is to send given authentication credentials to OpenAM and if authentication succeeds, then manager will set returned token in response cookie. HttpServletResponse can be autowired in authentication manager component, se there should be no problem in setting appropriate cookie, or response code (see http://stackoverflow.com/questions/5629993/spring-mvc-response).
- OpenAmAuthenticationFilter - filter will intercept requests and it will send token from specified cookie to OpenAM for validation
Api specification: https://wikis.forgerock.org/confluence/display/openam/Use+OpenAM+RESTful+Services#UseOpenAMRESTfulServices-Authentication
Updated by Radek Tomiška over 7 years ago
- Precedes Task #309: OAuth2 - proof of concept added
Updated by Radek Tomiška over 7 years ago
- Assignee changed from Radek Tomiška to Alena Peterová
I don't see any obvious obstacle in implementation by this design, its ok, i like it. Well, after #309 will be merger into develop, implementation could start.
Updated by Alena Peterová over 7 years ago
Several questions and use-cases we discussed with Honza and Peter:
1) Users are authenticated with their login and password by OpenAM. Should they be assigned internal IdM authentication token - JWT token, or not? If yes, should the creation of IdmJwtAuthentication (setting of the granted authorities, auth expiration etc.) be done in the OpenAMAuthenticator?
- Yes, they should have JWT token, it's needed for correct handling of their grants in IdM
- Creation of IdmJwtAuthentication should be hidden, OpenAMAuthenticator shouldn't explicitly set auth expiration or grants, that should be set from core configuration. There should be some 'util' method in SecurityService, which will get basic information - what identity is authenticated, which module authenticates the user. This method will handle the rest. (Now the same code of creating IdmJwtAuthentication is in DefaultLoginService and DefaultAccAuthenticator, that should be refactored.)
- Most secure solution would be to log the user out of IdM immediately. OpenAmAuthenticationFilter would either break the filter chain by commiting the error response (so JwtAuthenticationFilter wouldn't even be called), or it would somehow invalidate JWT token (so JwtAuthenticationFilter would get called, but wouldn't authorize the user).
- Immediate logout has several problems:
- The OpenAmAuthenticationFilter can't commit error response every time, because then even login page wouldn't be loaded - this should be solved by #473
- What if user was authenticated by local IdM storage (e.g. it's an admin account which doesn't exist in OpenAM)? Such user would be always logged out by OpenAmAuthenticationFilter. But that's not what we want, we need local admins.
3) What if user 'localAdmin' has valid IdM session and at the same time he has valid OpenAM cookie, which corresponds to user 'openamTestUser'? Which user should be authenticated to IdM?
4) When user logs out of IdM, currently it only deletes his JWT token in fronted. What should happen fro users authenticated by OpenAM?
- We should delete OpenAM cookie (which can be done at fronted) and invalidate their session by OpenAM (by calling OpenAM REST /logout).
- If we don't invalidate their sessions, the token would be still valid, which is not really safe. Moreover we could hit the sessions limit in OpenAM (one user can have at most 5 active sessions).
Updated by Alena Peterová over 7 years ago
- Related to Task #478: Ignore disabled IdmAuthenticationFilter added
Updated by Alena Peterová over 7 years ago
- Related to Feature #499: Logout endpoint on backend added
Updated by Alena Peterová over 7 years ago
- Status changed from New to Needs feedback
- Assignee changed from Alena Peterová to Radek Tomiška
- % Done changed from 0 to 80
New OpenAM module is implemented in the branch personal/AlenaPeterova/feature-OpenAM-module-#360 in modules repository.
Several TODOs need to be resolved, namely:- how/where to refactor code which creates JWT token. It probably shouldn't be part of external module (OpenAMAuthenticationUtils), but there should be some util method in core
- invalidate JWT token when the OpenAM session expired and user was previously authenticated by OpenAM (OpenAMIdmAuthenticationFilter) - how, where (again - some core util method?)
- integration test for REST endpoint which returns attributes for OpenAM - clean configuration programatically somehow?
- exception handling - I'm not sure if the exception from external services (OpenAM) should be only logged as it is now, or wrapped and thrown again. If the external service is unavailable, we should still be able to work in IdM (at least local admins), so it still needs to be handled somewhere.
Please provide feedback, thanks.
Updated by Radek Tomiška over 7 years ago
- Category set to Authentication / Authorization
- Status changed from Needs feedback to In Progress
- Assignee changed from Radek Tomiška to Alena Peterová
- Target version set to Diamond (7.4.0)
- HttpClient can be reused in DefaultOpenAMHttpCaller - will be called in every request, if filter will be active
- javadoc in intefaces is perfect. Only somewhere is missing @author and public modifier is not necessary .)
- Configurable interface is used nicely. Use @Component annotation instead @Confugration (is used mainly for @Bean creation)
- i've added new PropertyModuleDescriptor to simplify module-*.properties usage - https://proj.bcvsolutions.eu/ngidm/doku.php?id=en:navrh:konfigurace_aplikace#module_configuration
- i prefer to use camelCase in 'OpenAm', but it's ok :)
Questions:
add OpenAMAuthenticationUtils) good idea - some new interface for OAuthAuthenticationManager to prevent static utils usage can be created. Could you please prepare this feature into new branch in develop (i don't know if token expiration setting will be unique)?
add invalidate JWT token) IdmAuthorityChange change mechanism can be reused / extended for this reason - we need persist some information about expired jwt tokens + logout feature can be implemented to the core.
add clean configuration) configurationService.setValue(key, null) can be used (+ finally set value back if needed), if i understood it well. We can prepare some test util "run under configuration".
add exceptions) I agree with your idea - identities should be authorized by other filters, if openAm fails. I think this is about filter mechanism design - https://proj.bcvsolutions.eu/ngidm/doku.php?id=navrh:oauth#cilova_implementace - Ondra prepared this mechanism, so we can finish it (i thing 'sufficient' option is implemented for now).
I don't test it for now (coming soon, i need to install openAM locally :)).
Updated by Alena Peterová over 7 years ago
- we don't need "SSO logout" for now - the IdM session will be valid as long as the user is active in IdM, even if the OpenAM token expired.
- the OpenAM authentication filter will be ordered after JWT authentication filter. So it will not be called for every request, which could decrease performance (checking token & creating JWT tokens). Still it will support SSO login (when users first get to IdM and have valid token, they will be logged in).
Footnote:
First point means that I don't need to solve JWT token invalidation at all. Yesterday I implemented it using IdmAuthorityChange change mechanism as Radek suggested, that worked well (only one little bug - #606), but I had problems determining if the user was authenticated by OpenAM, or core. (The problem was in SSO login - call to /remote-auth endpoint resulted to setting JWT token from core and the frontend "remembered" this token for the whole user session. So when the OpenAM token was expired, user's session still was not invalidated because the filter thought it was authenticated by core. Maybe loginAuthenticatedUser should set information about module from current authentication.)
Updated by Alena Peterová over 7 years ago
- Assignee changed from Alena Peterová to Radek Tomiška
Review notes processed + added new necessary functions (will be used in a project module):
Changes are in:
- core: apeterova/360-create-jwt-authentication-refactor (refactoring of JWT token creation)
- modules: personal/AlenaPeterova/feature-OpenAM-module-#360
Please provide feedback.
Documentation is not written yet, I will put it probably in the README of the module.
Updated by Radek Tomiška over 7 years ago
- Assignee changed from Radek Tomiška to Alena Peterová
- % Done changed from 80 to 90
I did test and review of core changes in branch apeterova/360-create-jwt-authentication-refactor. It works and code looks nice, thx! I've merged branch into develop.
I did quick review of openam module, code looks good too. Maybe we don't need to use the same version as core for openam module and start from 1.0.0.
Updated by Alena Peterová over 7 years ago
Thank you. I changed the version of the module to 1.0.0-SNAPSHOT and version of core dependencies.
Updated by Alena Peterová over 7 years ago
- Status changed from In Progress to Resolved
- % Done changed from 90 to 100
apeterova/360-create-jwt-authentication-refactor was also merged to hotfix-7.3.3.
Documentation of the module was added to README.md in the root of the module.
OpenAM module version 1.0.0 released with dependency on CzechIdM core 7.3.3.
Resolved.
Updated by Radek Tomiška over 7 years ago
- Status changed from Resolved to Closed