Spring mvc Spring安全性-用户身份验证有时会失败,用户被重定向到登录页面
我的环境:Spring mvc Spring安全性-用户身份验证有时会失败,用户被重定向到登录页面,spring-mvc,session,spring-security,Spring Mvc,Session,Spring Security,我的环境: 爪哇6 Servlet 2.5 Weblogic 12.1 Spring MVC 4.3.4.1版本 Spring Security 4.2.0.0版本 我已经实现了一个CustomAuthenticationProvider,以便针对Oracle db对用户进行身份验证:用户实际上是db用户,因此我尝试连接到db以检查用户/密码,如果结果是肯定的,则加载权限 除了登录错误之外,配置工作正常。如果用户键入错误的用户名或密码,则应用程序会在同一页面中显示错误消息,但如果用户再次正确
- 爪哇6
- Servlet 2.5
- Weblogic 12.1
- Spring MVC 4.3.4.1版本
- Spring Security 4.2.0.0版本
@Component
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private Logger log = LogManager.getLogger(CustomAuthenticationProvider.class);
@Autowired
private UserService userService;
@Autowired
private SecurityService securityService;
@Autowired
private Messages messages;
@Value("${login.test.mode}")
private String testMode;
@Value("${login.test.mode.userid}")
private String testModeUserid;
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
log.debug("##### SECURITY ##### Test mode status: " + testMode);
// test mode uses its own configured user, ignoring login credentials, if username is empty
if (Constants.FLAG_YES.equals(testMode) && StringUtils.isEmpty(username)) {
username = testModeUserid;
}
GddbUserDetails gddbUserDetails = userService.findGddbUserDetailsByUsername(username);
UserRole userRole = userService.findUserRolesByUsername(username);
if (gddbUserDetails == null) {
log.debug("##### SECURITY ##### Utente non trovato in anagrafica GDDB: " + username);
throw new BadCredentialsException(messages.get("user.not.found.gddb"));
} else {
log.debug("##### SECURITY ##### OK Utente trovato in anagrafica GDDB: " + username);
}
// perform checks only if test mode is disabled
if (!Constants.FLAG_YES.equals(testMode)) {
// GDDB state check
if (!Constants.USER_STATO_ACTIVE.equals(gddbUserDetails.getStato())) {
log.debug("##### SECURITY ##### Utente presente in anagrafica GDDB ma disabilitato: " + username);
throw new BadCredentialsException(messages.get("user.not.enabled.gddb"));
} else {
log.debug("##### SECURITY ##### Utente presente in anagrafica GDDB e abilitato: " + username);
}
// dbetichette user existence check
if (userRole == null) {
log.debug("##### SECURITY ##### Utente non presente in anagrafica DBEtichette: " + username);
throw new BadCredentialsException(messages.get("user.not.enabled.locally"));
} else {
log.debug("##### SECURITY ##### Utente presente in anagrafica DBEtichette: " + username);
}
// dbetichette user activation check
if (!Constants.FLAG_YES.equals(userRole.getActive())) {
log.debug("##### SECURITY ##### Utente disabilitato in anagrafica DBEtichette: " + username);
throw new BadCredentialsException(messages.get("user.not.enabled.locally"));
} else {
log.debug("##### SECURITY ##### Utente abilitato in anagrafica DBEtichette: " + username);
}
// oracle user password check
String usernamePasswordCheckResult = securityService.checkUserPassword(username, password);
log.debug("##### SECURITY ##### usernamePasswordCheckResult: " + usernamePasswordCheckResult);
if (Constants.SECURITY_ACCOUNT_LOCKED.equals(usernamePasswordCheckResult)) {
log.debug("##### SECURITY ##### Utente presente su DB ma bloccato: " + username);
throw new BadCredentialsException(messages.get("user.blocked"));
} else if (Constants.SECURITY_PASSWORD_EXPIRED.equals(usernamePasswordCheckResult)) {
log.debug("##### SECURITY ##### Password dell'utente scaduta: " + username);
throw new BadCredentialsException(messages.get("user.password.expired"));
} else if (Constants.SECURITY_INVALID_USERNAME_PASSWORD.equals(usernamePasswordCheckResult)) {
log.debug("##### SECURITY ##### Tentativo di accesso fallito per errata password: " + username);
throw new BadCredentialsException(messages.get("user.password.wrong"));
} else if (!Constants.SECURITY_VALID_USERNAME_PASSWORD.equals(usernamePasswordCheckResult)) {
log.debug("##### SECURITY ##### Tentativo di accesso fallito per motivo sconosciuto: " + username
+ " ( usernamePasswordCheckResult = " + usernamePasswordCheckResult + " )");
throw new BadCredentialsException(messages.get("user.login.error.other"));
} else {
log.debug("##### SECURITY ##### Tentativo di accesso eseguito con successo: " + usernamePasswordCheckResult + " - " + username);
}
}
CustomUser user = userService.createCustomUser(gddbUserDetails, userRole);
log.debug("##### SECURITY ##### Creazione custom user: " + user);
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
UsernamePasswordAuthenticationToken userToken = new UsernamePasswordAuthenticationToken(user, password, authorities);
log.debug("##### SECURITY ##### Creazione userToken: " + userToken);
return userToken;
}
@Override
protected UserDetails retrieveUser(String s, UsernamePasswordAuthenticationToken token) throws AuthenticationException {
UserDetails user = (UserDetails) token.getPrincipal();
log.debug("##### SECURITY ##### retrieveUser: " + user);
return user;
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken token) throws AuthenticationException {
log.debug("##### SECURITY ##### additionalAuthenticationChecks - userDetails " + userDetails);
log.debug("##### SECURITY ##### additionalAuthenticationChecks - token " + token);
}
}
我想重要的一点是:
[DEBUG] 2017-02-17 17:01:41.317 org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession is now null, but was not null at start of request; session was invalidated, so do not create a new session
为什么这种情况只在某些环境中偶尔发生?阅读不同但相似问题的解决方案,我猜我的问题也是一个并发问题,与会话管理有关 因此,我尝试在我的
securityConfig.xml
中为会话管理设置显式配置,将每个用户允许的身份验证会话数限制为1:
<session-management session-fixation-protection="newSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
这些更改完全解决了问题。为什么-1?有人说,我的问题没有显示任何研究成果,或者可能不清楚和/或没有用处:/
[DEBUG] 2017-02-17 17:01:41.317 org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession is now null, but was not null at start of request; session was invalidated, so do not create a new session
<session-management session-fixation-protection="newSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>