Принудительное изменение пользователем пароля с истекшим сроком в весенней безопасности - PullRequest
12 голосов
/ 12 декабря 2011

Я создаю Spring MVC и Spring Security на основе веб-приложения.

Я реализовал функцию сброса пароля. Системный администратор сбросит пароль любого пользователя. Сгенерированный случайным образом пароль будет отправлен пользователю по электронной почте, и он будет обновлен в базе данных.

Теперь я хочу, чтобы всякий раз, когда пользователь входил в систему со случайно сгенерированным паролем, я хотел заставить пользователя сменить свой пароль.

Пожалуйста, взгляните на моего пользователя TABLE.

идентификатор пользователя bigint (20)
имя пользователя varchar (20)
пароль varchar (65)
электронная почта varchar (50)
имя varchar (20)
фамилия варчар (20)
название группы varchar (50)
включен tinyint (1)
учетные данныеNonExpired tinyint (1)

МОЙ поставщик аутентификации

    <!--
        Configuring Authentication Provider to make use of spring security
        provided Jdbc user management service
    -->
    <authentication-provider user-service-ref="jdbcUserService">
        <!--
            Configuring SHA-1 Password Encoding scheme to secure user credential
        -->
        <password-encoder ref="sha1PasswordEncoder" />
    </authentication-provider>
</authentication-manager>

Я использовал JDBCUserDetailsService расширение JDBCDaoImpl как jdbcUserService .

Я хочу установить credentialNonExpired в ложный столбец моей пользовательской таблицы при сбросе пароля.

Я могу это сделать.

Но при входе в систему пружина безопасности JDBCuserdetailsservice loadUserbyUsername получает только имя пользователя, пароль, включенные столбцы и остальные поля, равные true.

protected List<UserDetails> loadUsersByUsername(String username) {
    return getJdbcTemplate().query(usersByUsernameQuery, new String[] {username}, new RowMapper<UserDetails>() {
        public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
            String username = rs.getString(1);
            String password = rs.getString(2);
            boolean enabled = rs.getBoolean(3);
            return new User(username, password, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
        }

    });
}

Но я хочу фактическое credentialNonExpired поле, которое устанавливается паролем сброса, чтобы пружинная защита выдавала CREDENTIALEXPIREDEXCEPTION.

Я добиваюсь этого, загружая вышеуказанный метод, но есть ли другой способ перенаправить пользователя на страницу смены пароля при входе в систему с просроченным паролем.

Скажите, пожалуйста, как я могу это сделать?

Ответы [ 2 ]

15 голосов
/ 17 января 2013

Довольно поздний ответ, и я не знаю, используете ли вы Spring 2 или 3. Но в Spring 3 вы можете сделать это следующим образом.

Включите в свой контекст безопасности Spring следующее:

<bean id="securityExceptionTranslationHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
    <property name="exceptionMappings">
        <props>
            <prop key="org.springframework.security.authentication.CredentialsExpiredException">/change_password_page</prop>
        </props>
    </property>
    <property name="defaultFailureUrl" value="/login_generic_error_page"/>
</bean>

Конечно, вы можете сопоставить другие конкретные исключения аутентификации с другими страницами.

Если вы используете элемент form-login, вам нужно указать атрибут authentication-failure-handler-ref (и удалитьauthentication-failure-url если используется)

<security:form-login ... authentication-failure-handler-ref="securityExceptionTranslationHandler">

И последний шаг - создание страницы смены пароля.

Имейте в виду, что пользователь не аутентифицируется при перенаправлении на страницу смены пароля.

1 голос
/ 12 января 2012

Вы можете попробовать создать подкласс SimpleUrlAuthenticationSuccessHandler и реализовать собственную логику для проверки срока действия пароля. Ссылка на этот SimpleUrlAuthenticationSuccessHandler может быть передана элементу form-login в контексте приложения.

...