我正在使用Spring 4和Hibernate 4我已經實現了Spring安全性及其工作正常,但是,我不想允許使用相同憑據的併發登錄。 1.我已經在web.xml中添加了Listener「HttpSessionEventPublisher」,並且在spring security中使用了「會話管理」標籤來實現併發控制,但它不起作用以下是完整的代碼:春季安全併發會話不工作
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
彈簧的security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="permitAll()" />
<intercept-url pattern="/loginError" access="isAnonymous()" />
<intercept-url pattern="/sessionTimeout" access="isAnonymous()" />
<intercept-url pattern="/forgotPassword" access="isAnonymous()" />
<intercept-url pattern="/requestNewPassword" access="isAnonymous()" />
<intercept-url pattern="/assets/**" access="permitAll()" />
<intercept-url pattern="/sessionExpired" access="isAnonymous()" />
<intercept-url pattern="/error" access="isAnonymous()" />
<form-login login-page="/login"
username-parameter="userId"
password-parameter="password"
authentication-success-handler-ref="cdatSuccessHandler"
authentication-failure-url="/loginError" />
<!-- <session-management session-fixation-protection="newSession" invalid-session-url="/sessionTimeout">
</session-management> -->
<session-management>
<concurrency-control max-sessions="1" expired-url="/sessionTimeout" />
</session-management>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<csrf/>
<!-- <access-denied-handler error-page="/sessionExpired"/> -->
<headers>
<xss-protection enabled="true" block="true"/>
</headers>
</http>
<authentication-manager erase-credentials="true">
<authentication-provider ref="cdatAuthenticationProvider"> </authentication-provider>
</authentication-manager>
身份驗證提供一流
package com.component.cdat.security.configuration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import com.component.cdat.project.bean.MappProjectUser;
import com.component.cdat.user.bean.User;
import com.component.cdat.user.services.UserService;
@Component("cdatAuthenticationProvider")
public class CDATAuthenticationProvider implements AuthenticationProvider{
@Autowired
UserService userService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String loginId = authentication.getName().trim();
String password = (String) authentication.getCredentials();
if(loginId == null || password == null || loginId.isEmpty() || password.isEmpty()){
// throw exception
System.out.println("username or password is empty!!");
throw new NullPointerException();
}
User user = userService.getUserByUserName(loginId);
if(user == null || !loginId.equalsIgnoreCase(user.getUserName())){
System.out.println("User Not Found!!");
throw new NullPointerException();
}
if(!password.equalsIgnoreCase(user.getPassword())){
System.out.println("Pasword is incorrect!!");
throw new NullPointerException();
}
Collection<? extends GrantedAuthority> authorities = getAuthorities(user);
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}
private Collection<? extends GrantedAuthority> getAuthorities(User user){
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
List<MappProjectUser> userAuthorityList = userService.getUserRole(user.getUserId());
for(MappProjectUser userAuthority : userAuthorityList){
authorities.add(new SimpleGrantedAuthority("ROLE_" + userAuthority.getUserType().getShortDesc()));
}
return authorities;
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
從安全的角度來看,password.equalsIgnoreCase(user.getPassword())可能不是一個好主意。你如何測試並得出結論,它不起作用? (例如,同一瀏覽器內的多個選項卡通常對給定站點使用相同的會話)。 – Thierry
不......我使用了不同的瀏覽器,並試圖在隱身模式下打開鏈接,但它允許我使用相同的憑據登錄。我們應該使用什麼來比較密碼以獲得更好的安全性? – susmit
對於密碼,請不要忽略該情況。 – Thierry