1) Is there a way to implement a custom login module that will authenticate users but still use Spring Security to manage access control after login and for logout.
Yes. You can provide your own authentication mechanism, by implementing org.springframework.security.authentication.AuthenticationProvider and making it a bean (annotating it or in XML) :
@Service("myAuthenticationProvider") public class
TangoAuthenticationProvider implements AuthenticationProvider{
@Override
public boolean supports(Class<?> authentication) {
//your code
}
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
//your code
}
Then , and instruct Spring security to use it (in your security context):
<authentication-manager>
<authentication-provider ref="tangoAuthenticationProvider" />
</authentication-manager>
See this question, and of course spring security doc.
2) Dynamically created roles : I can't answer thios part, no experience with this.
3) Single session requirement
Maybe there is sucha a mechanism built in Spring Security (you' d have to research this), but I think you can implement it using simple session listeners and the afore-mentionned custom authentication mechanism :
- Add a session id field to you user entity (or somewhere else, but somehow associate your user id with a session id)
Create a service that allows to store a reference to a session associated with its id, and provide access to the session by its id. You could use a static hashmap, or a singleton, or better, a Spring service bean with roughly the following interface (let's call it the session repository):
public void putSession(String id, HttpSession session);
public HttpSession getSessionById(String id);
In your authentication provider, after a successful login, set the user's session id field to the current session id
- In the authentication logic, if the sessionId field of the user is not null either forbid the authentication (then you wouldn't need the reference to the session mechanism thing), or, more likely to be the real requirement, proceed to invalidate the user's other ongoing session, by getting it from the session repository using the user's sessionId field's value
- In a session listener :
On session created : store session in the session repository
On session deleted : if there is a logged in user, clear its sessionId field; clear the reference to the session in order to avoid memory leak.
This is sensitive code in relation to security (cross-session stuff) so it should be written and tested very carefully though !
I hope it helps.