use of com.albedo.java.modules.sys.domain.PersistentTokenDo in project albedo by somowhere.
the class PersistentTokenRememberMeService method processAutoLoginCookie.
@Override
protected UserDetails processAutoLoginCookie(String[] cookieTokens, HttpServletRequest request, HttpServletResponse response) {
// prevent 2 authentication requests from the same user in parallel
synchronized (this) {
if (cookieTokens == null) {
return null;
}
String login = null;
UpgradedRememberMeToken upgradedToken = upgradedTokenCache.get(cookieTokens[0]);
if (upgradedToken != null) {
login = upgradedToken.getUserLoginIfValid(cookieTokens);
log.debug("Detected previously upgraded login token for user '{}'", login);
}
if (login == null) {
PersistentTokenDo persistentTokenDo = getToken(cookieTokens);
UserDo userDo = userRepository.selectById(persistentTokenDo.getUserId());
login = userDo.getUsername();
// Token also matches, so login is valid. Update the token value, keeping
// the *same* series number.
log.debug("Refreshing persistent login token for user '{}', series '{}'", login, persistentTokenDo.getSeries());
persistentTokenDo.setTokenDate(LocalDateTime.now());
persistentTokenDo.setTokenValue(RandomUtil.generateTokenData());
persistentTokenDo.setIpAddress(WebUtil.getIp(request));
persistentTokenDo.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
try {
persistentTokenRepository.updateById(persistentTokenDo);
} catch (DataAccessException e) {
log.error("Failed to update token: ", e);
throw new RememberMeAuthenticationException("Autologin failed due to data access problem", e);
}
addCookie(persistentTokenDo, request, response);
upgradedTokenCache.put(cookieTokens[0], new UpgradedRememberMeToken(cookieTokens, login));
}
return getUserDetailsService().loadUserByUsername(login);
}
}
use of com.albedo.java.modules.sys.domain.PersistentTokenDo in project albedo by somowhere.
the class PersistentTokenRememberMeService method getToken.
/**
* Validate the token and return it.
*/
private PersistentTokenDo getToken(String[] cookieTokens) {
if (cookieTokens.length != TOKEN_LENGTH) {
throw new InvalidCookieException("Cookie token did not contain " + TOKEN_LENGTH + " tokens, but contained '" + Arrays.asList(cookieTokens) + "'");
}
String presentedSeries = cookieTokens[0];
String presentedToken = cookieTokens[1];
PersistentTokenDo persistentTokenDo = persistentTokenRepository.selectById(presentedSeries);
if (persistentTokenDo == null) {
// No series match, so we can't authenticate using this cookie
throw new RememberMeAuthenticationException("No persistent token found for series id: " + presentedSeries);
}
// We have a match for this user/series combination
log.info("presentedToken={} / tokenValue={}", presentedToken, persistentTokenDo.getTokenValue());
if (!presentedToken.equals(persistentTokenDo.getTokenValue())) {
// Token doesn't match series value. Delete this session and throw an
// exception.
persistentTokenRepository.deleteById(persistentTokenDo.getSeries());
throw new CookieTheftException("Invalid remember-me token (Series/token) mismatch. Implies previous " + "cookie theft attack.");
}
if (persistentTokenDo.getTokenDate().plusDays(TOKEN_VALIDITY_DAYS).isBefore(LocalDateTime.now())) {
persistentTokenRepository.deleteById(persistentTokenDo.getSeries());
throw new RememberMeAuthenticationException("Remember-me login has expired");
}
return persistentTokenDo;
}
use of com.albedo.java.modules.sys.domain.PersistentTokenDo in project albedo by somowhere.
the class PersistentTokenRememberMeService method logout.
/**
* When logout occurs, only invalidate the current token, and not all user sessions.
* <p>
* The standard Spring Security implementations are too basic: they invalidate all
* tokens for the current user, so when he logs out from one browser, all his other
* sessions are destroyed.
*
* @param request the request.
* @param response the response.
* @param authentication the authentication.
*/
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
String rememberMeCookie = extractRememberMeCookie(request);
if (rememberMeCookie != null && rememberMeCookie.length() != 0) {
try {
String[] cookieTokens = decodeCookie(rememberMeCookie);
PersistentTokenDo persistentTokenDo = getToken(cookieTokens);
persistentTokenRepository.deleteById(persistentTokenDo.getSeries());
} catch (InvalidCookieException ice) {
log.info("Invalid cookie, no persistent token could be deleted", ice);
} catch (RememberMeAuthenticationException rmae) {
log.debug("No persistent token found, so no token could be deleted", rmae);
}
}
super.logout(request, response, authentication);
}
use of com.albedo.java.modules.sys.domain.PersistentTokenDo in project albedo by somowhere.
the class PersistentTokenRememberMeService method onLoginSuccess.
@Override
protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
String login = successfulAuthentication.getName();
log.debug("Creating new persistent login for user {}", login);
PersistentTokenDo persistentTokenDo = Optional.of(userRepository.findVoByUsername(login)).map(u -> {
PersistentTokenDo t = new PersistentTokenDo();
t.setSeries(RandomUtil.generateSeriesData());
t.setUserId(u.getId());
t.setUsername(u.getUsername());
t.setTokenValue(RandomUtil.generateTokenData());
t.setTokenDate(LocalDateTime.now());
t.setIpAddress(WebUtil.getIp(request));
t.setLoginLocation(AddressUtil.getRegion(t.getIpAddress()));
t.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
UserAgent userAgent = UserAgentUtil.parse(t.getUserAgent());
t.setBrowser(userAgent.getBrowser().getName());
t.setOs(userAgent.getOs().getName());
return t;
}).orElseThrow(() -> new UsernameNotFoundException("User " + login + " was not found in the database"));
try {
persistentTokenRepository.insert(persistentTokenDo);
addCookie(persistentTokenDo, request, response);
} catch (DataAccessException e) {
log.error("Failed to save persistent token ", e);
}
}
Aggregations