Search in sources :

Example 1 with PersistentTokenDo

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);
    }
}
Also used : RememberMeAuthenticationException(org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException) UserDo(com.albedo.java.modules.sys.domain.UserDo) PersistentTokenDo(com.albedo.java.modules.sys.domain.PersistentTokenDo) DataAccessException(org.springframework.dao.DataAccessException)

Example 2 with PersistentTokenDo

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;
}
Also used : RememberMeAuthenticationException(org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException) InvalidCookieException(org.springframework.security.web.authentication.rememberme.InvalidCookieException) CookieTheftException(org.springframework.security.web.authentication.rememberme.CookieTheftException) PersistentTokenDo(com.albedo.java.modules.sys.domain.PersistentTokenDo)

Example 3 with 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);
}
Also used : RememberMeAuthenticationException(org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException) InvalidCookieException(org.springframework.security.web.authentication.rememberme.InvalidCookieException) PersistentTokenDo(com.albedo.java.modules.sys.domain.PersistentTokenDo)

Example 4 with PersistentTokenDo

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);
    }
}
Also used : UserRepository(com.albedo.java.modules.sys.repository.UserRepository) DataAccessException(org.springframework.dao.DataAccessException) Arrays(java.util.Arrays) UsernameNotFoundException(org.springframework.security.core.userdetails.UsernameNotFoundException) UserDetailsService(org.springframework.security.core.userdetails.UserDetailsService) LocalDateTime(java.time.LocalDateTime) PersistentTokenRepository(com.albedo.java.modules.sys.repository.PersistentTokenRepository) UserAgent(cn.hutool.http.useragent.UserAgent) AddressUtil(com.albedo.java.common.core.util.AddressUtil) HttpServletRequest(javax.servlet.http.HttpServletRequest) PersistentTokenDo(com.albedo.java.modules.sys.domain.PersistentTokenDo) UserDo(com.albedo.java.modules.sys.domain.UserDo) UserDetails(org.springframework.security.core.userdetails.UserDetails) RememberMeAuthenticationException(org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException) CookieTheftException(org.springframework.security.web.authentication.rememberme.CookieTheftException) WebUtil(com.albedo.java.common.core.util.WebUtil) HttpHeaders(org.springframework.http.HttpHeaders) RandomUtil(com.albedo.java.common.security.util.RandomUtil) HttpServletResponse(javax.servlet.http.HttpServletResponse) UserAgentUtil(cn.hutool.http.useragent.UserAgentUtil) InvalidCookieException(org.springframework.security.web.authentication.rememberme.InvalidCookieException) Serializable(java.io.Serializable) Slf4j(lombok.extern.slf4j.Slf4j) Component(org.springframework.stereotype.Component) ApplicationProperties(com.albedo.java.common.core.config.ApplicationProperties) Optional(java.util.Optional) AbstractRememberMeServices(org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices) Authentication(org.springframework.security.core.Authentication) UsernameNotFoundException(org.springframework.security.core.userdetails.UsernameNotFoundException) UserAgent(cn.hutool.http.useragent.UserAgent) PersistentTokenDo(com.albedo.java.modules.sys.domain.PersistentTokenDo) DataAccessException(org.springframework.dao.DataAccessException)

Aggregations

PersistentTokenDo (com.albedo.java.modules.sys.domain.PersistentTokenDo)4 RememberMeAuthenticationException (org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException)4 InvalidCookieException (org.springframework.security.web.authentication.rememberme.InvalidCookieException)3 UserDo (com.albedo.java.modules.sys.domain.UserDo)2 DataAccessException (org.springframework.dao.DataAccessException)2 CookieTheftException (org.springframework.security.web.authentication.rememberme.CookieTheftException)2 UserAgent (cn.hutool.http.useragent.UserAgent)1 UserAgentUtil (cn.hutool.http.useragent.UserAgentUtil)1 ApplicationProperties (com.albedo.java.common.core.config.ApplicationProperties)1 AddressUtil (com.albedo.java.common.core.util.AddressUtil)1 WebUtil (com.albedo.java.common.core.util.WebUtil)1 RandomUtil (com.albedo.java.common.security.util.RandomUtil)1 PersistentTokenRepository (com.albedo.java.modules.sys.repository.PersistentTokenRepository)1 UserRepository (com.albedo.java.modules.sys.repository.UserRepository)1 Serializable (java.io.Serializable)1 LocalDateTime (java.time.LocalDateTime)1 Arrays (java.util.Arrays)1 Optional (java.util.Optional)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1