春季限制最多会话;限制最大用户

时间:2010-01-21 02:55:58

标签: java spring spring-security

我是否可以使用spring security来限制能够同时登录网站的最大用户数?

肯定不是并发会话控制参数。我想要的是,例如,我想限制最大只允许1000个用户同时登录。如果超过前向通知页面,说明最大用户超过

3 个答案:

答案 0 :(得分:8)

您可以通过访问SessionRegistry来查看当前登录的用户数量来使用Spring Security的并发会话控制。在Spring Security 3中,ConcurrentSessionControlStrategy负责控制是否允许用户在登录后创建会话。您可以扩展此类并根据用户数添加额外的检查:

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);
    }
}

然后按照the Spring Security reference manual

中的描述将其注入安全名称空间

在Spring Security 2.0中,并发会话控制的实现略有不同,您可以自定义ConcurrentSessionController。

答案 1 :(得分:1)

我没有足够的声誉来添加评论。但getAllPrincipals返回所有主体,包括来自过期会话的主体。使用如下方法获取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();
}

答案 2 :(得分:0)

这篇文章有点陈旧,但我在spring security 4.1中遇到了同样的问题,我已经解决了这个问题。

会话管理

<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>

会话的认证策略-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;

验证

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.");
}

以这种方式,因为我基于安全性进行身份验证:custom-filter