spring limit max sessions ; limit max users

后端 未结 3 1810
你的背包
你的背包 2020-12-16 07:04

may i know possible to use spring security to limit max number of users able to login to website at the same time?

definately, not concurrent-session-control parame

相关标签:
3条回答
  • 2020-12-16 07:29

    You can use Spring Security's concurrent session control by accessing the SessionRegistry to find out how many users are currently logged in. In Spring Security 3, the ConcurrentSessionControlStrategy is responsible for controlling whether the user is allowed to create a session after logging in. You can extend this class and add an extra check based on the number of users:

    public class MySessionAuthenticationStrategy extends ConcurrentSessionControlStrategy {
        int MAX_USERS = 1000; // Whatever
        SessionRegistry sr;
    
        public MySessionAuthenticationStrategy(SessionRegistry sr) {
            super(sr);
            this.sr = sr;
        }
    
        @Override
        public void onAuthentication(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
            if (sr.getAllPrincipals().size() > MAX_USERS) {
                throw new SessionAuthenticationException("Maximum number of users exceeded");
            }
            super.onAuthentication(authentication, request, response);
        }
    }
    

    You would then inject this into the security namespace as described in the Spring Security reference manual.

    In Spring Security 2.0, the concurrent session control is implemented slightly differently and you would customize the ConcurrentSessionController instead.

    0 讨论(0)
  • 2020-12-16 07:35

    I do not have enough reputation to add a comment. But getAllPrincipals returns all principals including ones from expired sessions. Use some method like below to getAllActiveSessions.

    private List<SessionInformation> getActiveSessions(SessionRegistry sessionRegistry) {
        final List<Object> principals = sessionRegistry.getAllPrincipals();
        if (principals != null) {
            List<SessionInformation> sessions = new ArrayList<>();
            for (Object principal : principals) {
                sessions.addAll(sessionRegistry.getAllSessions(principal,     false));
            }
            return sessions;
        }
        return Collections.emptyList();
    }
    
    0 讨论(0)
  • 2020-12-16 07:40

    this post is a bit old but I have had the same problem in spring security 4.1 and I have solved it like that.

    session-management

    <security:http disable-url-rewriting="true" use-expressions="true" auto-config="true">
        <security:session-management  invalid-session-url="/app/login" session-authentication-strategy-ref="sessionAuthenticationStrategy">                                   
        </security:session-management>
    </security:http>
    

    session-authentication-strategy-ref

    <bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
                <constructor-arg ref="sessionRegistry"/>
                <property name="maximumSessions" value="1" />
                <property name="exceptionIfMaximumExceeded" value="true" />
            </bean>
            <bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
            </bean>
            <bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
                <constructor-arg ref="sessionRegistry"/>
            </bean>
        </list>
    </constructor-arg>
    </bean>
    

    SessionRegistry

    @Autowired
    private SessionRegistry sessionRegistry;
    

    Authentication

    List<SessionInformation> sessions = new ArrayList<>();
    for (Object principal : sessionRegistry.getAllPrincipals()) {
        sessions.addAll(sessionRegistry.getAllSessions(principal, false));
    }
    LOGGER.info("Sessiones Activas: " + sessions.size());
    // filtro para limite de sessiones
    if (sessions.size() < max_sessions) {
    //authentication
    } else {
        throw new SessionAuthenticationException("Maximo numero de Usuarios exedido.");
    }
    

    in this way because I am authenticating based on security: custom-filter

    0 讨论(0)
提交回复
热议问题