es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Seguridad de Primavera, el usuario remoto se vuelve nulo después de que expire la sesión.

Aquí está mi configuración de seguridad de Spring.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

private String sLogoutUrl_;

private String sLoginPage_;

private String sLoginSuccessUrl_;

public WebSecurityConfig() {
    sLogoutUrl_ = LnProperty.getSecurity(LnProperty.LOGOUTURL);
    sLoginPage_ = LnProperty.getSecurity(LnProperty.LOGINPAGE);
    sLoginSuccessUrl_ = LnProperty.getSecurity(LnProperty.LOGINSUCCESSURL);
}

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(username -> {
        TomcatUser tomcatUser = LnProperty.getUser(username);
        if (tomcatUser == null) {
            throw new UsernameNotFoundException(username);
        }
        return new User(username, passwordEncoder().encode(tomcatUser.getPassword()), tomcatUser.getRoles());
    });
}

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("**").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginPage(sLoginPage_)
        .loginProcessingUrl(sLoginPage_)
        .defaultSuccessUrl(sLoginSuccessUrl_, true)
        .failureHandler(authenticationFailureHandler(sLoginPage_))
        .and()
        .logout()
        .logoutUrl(sLogoutUrl_)
        .logoutSuccessHandler(logoutSuccessHandler(sLoginPage_))
        .deleteCookies("JSESSIONID");
}

@Bean 
public AuthenticationFailureHandler authenticationFailureHandler(String failureUrl) { 
    return new CustomAuthenticationFailureHandler(failureUrl); 
}

@Bean 
public LogoutSuccessHandler logoutSuccessHandler(String successUrl) { 
    return new CustomLogoutSuccessHandler(successUrl); 
}

@Bean 
public PasswordEncoder passwordEncoder() { 
    return new BCryptPasswordEncoder(); 
}

}

Intenté agregar esto a http pero no funcionó.

.and()
.rememberMe()
.alwaysRemember(true);

¿Hay alguna manera de permanecer conectado incluso después de que se agote la sesión? Está bien si los atributos de sesión se borran, pero quiero que el usuario remoto no se anule después de que se agote la sesión. Solo desconecte al usuario si se ingresa la URL de desconexión, se cierra el navegador o se eliminan las cookies / cachés.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma de mantener la sesión iniciada incluso después del tiempo de espera en Spring Security. Puedes usar la autenticación de recordar sesión persistente agregando el siguiente código a tu método configure():

    http
        .rememberMe()
            .tokenRepository(persistentTokenRepository())
            .tokenValiditySeconds(86400)
            .userDetailsService(userDetailsService)
    

    Esto creará un repositorio de token persistente y establecerá el tiempo de validez del token en 86400 segundos (1 día). El userDetailsService se usa para cargar los datos del usuario cuando se presenta un token.

    También necesitas crear un repositorio de token persistente implementando la interfaz PersistentTokenRepository. Aquí hay un ejemplo:

    public class JdbcTokenRepositoryImpl extends JdbcTokenRepositoryImpl {
        private final String INSERT_STATEMENT = "INSERT INTO persistent_logins (username, series, token, last_used) VALUES(?,?,?,?)";
        private final String SELECT_STATEMENT = "SELECT username, series, token, last_used FROM persistent_logins WHERE series = ?";
        private final String UPDATE_STATEMENT = "UPDATE persistent_logins SET token = ?, last_used = ? WHERE series = ?";
        private final String DELETE_STATEMENT = "DELETE FROM persistent_logins WHERE series = ?";
    
        private JdbcTemplate jdbcTemplate;
    
        public JdbcTokenRepositoryImpl(DataSource dataSource) {
            setDataSource(dataSource);
            jdbcTemplate = new JdbcTemplate(dataSource);
        }
    
        @Override
        public void createNewToken(PersistentRememberMeToken token) {
            jdbcTemplate.update(INSERT_STATEMENT, token.getUsername(), token.getSeries(), token.getTokenValue(), token.getDate());
        }
    
        @Override
        public void updateToken(String series, String tokenValue, Date lastUsed) {
            jdbcTemplate.update(UPDATE_STATEMENT, tokenValue, lastUsed, series);
        }
    
        @Override
        public PersistentRememberMeToken getTokenForSeries(String seriesId) {
            try {
                return jdbcTemplate.queryForObject(SELECT_STATEMENT, new RowMapper() {
                    public PersistentRememberMeToken mapRow(ResultSet rs, int rowNum) throws SQLException {
                        return new PersistentRememberMeToken(rs.getString("username"), rs.getString("series"), rs.getString("token"), rs.getTimestamp("last_used"));
                    }
                }, seriesId);
            } catch (EmptyResultDataAccessException e) {
                return null;
            }
        }
    
        @Override
        public void removeUserTokens(String username) {
            jdbcTemplate.update(DELETE_STATEMENT, username);
        }
    }
    

    Esta implementación de PersistentTokenRepository utiliza JDBC para almacenar los tokens en una tabla de base de datos llamada persistent_logins. Puedes personalizarla para usar cualquier otro mecanismo de almacenamiento que prefieras.

    Con esta configuración, el usuario permanecerá iniciado en sesión incluso después del tiempo de espera siempre y cuando la cookie de recordar sesión aún sea válida.

Comments are closed.