Доступ к переменной аутентификации из LogoutHandler или LogoutFilter в безопасности Spring - PullRequest
0 голосов
/ 01 февраля 2012

В одном из моих проектов я настроил Spring Security для обработки аутентификации пользователей.

Мой конфигурационный файл выглядит так:

<http use-expressions="true">
    <intercept-url pattern="/" access="permitAll()" />
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <form-login default-target-url="/main" login-page="/" always-use-default-target="true" username-parameter="userId" password-parameter="password" />
    <custom-filter ref="customLogoutFilter" position="LOGOUT_FILTER"/-->
    <session-management invalid-session-url="/" session-authentication-strategy-ref="sas" />
</http>

<beans:bean id="sas" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />

<beans:bean id="customLogoutHandler" class="com.somepack.CustomLogoutHandler"/>

<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <beans:constructor-arg index="0" ref="customLogoutHandler"/>
    <beans:constructor-arg index="1" ref="customLogoutFilter"/>
    <beans:property name="filterProcessesUrl" value="/"/>
</beans:bean>

<beans:bean id="customLogoutFilter" class="com.somepack.CustomLogoutFilter">
    <beans:property name="reportDir" value="/tmp/reports"/> 
</beans:bean>

Мой класс CustomLogoutFilter выглядит как

public class CustomLogoutFilter implements LogoutHandler {
    private String reportDir;
    public String getReportDir() {
        return reportDir;
    }
    public void setReportDir(String reportDir) {
        this.reportDir = reportDir;
    }
    @Override
    public void logout(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication) {
        String userName = authentication.getName();
        File folder = new File(reportDir, userName);
        deleteDir(folder); //delete function to delete Logged User specific directory
        logService.info("Logout", userName, EventCode.LOGOUT,
                String.format("User %s logged out successfully", userName));
        for (Cookie cookie : request.getCookies()) {
            printcookies(cookie);
            if (cookie.equals("JSESSIONID")) {
                cookie.setMaxAge(0);
                response.addCookie(cookie);
            }
        }
        request.getSession().invalidate();
    }   
}

Но этот фрагмент кода не работает, так как фильтр вызывается при самом первом запросе страницы входа (даже если он может вызываться при каждом запросе), и я получаю исключение NullPointerException в Строка userName = authentication.getName () строка.

Фактически, вместо использования LogoutFilter, если я использую Logouthandler, я получаю ту же ошибку:

Мой обработчик выглядит так:

public class CustomLogoutHandler extends AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler{
    private String reportDir;
    public String getReportDir() {
        return reportDir;
    }
    public void setReportDir(String reportDir) {
        this.reportDir = reportDir;
    }
    @Override
    public void onLogoutSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication) throws IOException,
            ServletException {
        String userName = authentication.getName();
        File folder = new File(reportDir, userName);
        deleteDir(folder);
        logService.info("Logout", userName, EventCode.LOGOUT, String.format("User %s logged out successfully", userName));
        super.handle(request, response, authentication);
    }

и файл конфигурации изменен на:

<http use-expressions="true">
    <intercept-url pattern="/" access="permitAll()" />
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <form-login default-target-url="/main" login-page="/" always-use-default-target="true" username-parameter="userId" password-parameter="password" />
    <logout delete-cookies="JSESSIONID" invalidate-session="true" success-handler-ref="customLogoutHandler" logout-url="/logout" />
    <session-management invalid-session-url="/" session-authentication-strategy-ref="sas" />
</http>

<beans:bean id="customLogoutHandler" class="sequent.ui.security.CustomLogoutHandler">
    <beans:property name="reportDir" value="/tmp/reports" />
</beans:bean>

Не уверен, как я могу решить эту проблему.

Пожалуйста, помогите.

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

Пожалуйста, оцените вашу помощь !!

-Raul

1 Ответ

0 голосов
/ 04 февраля 2012

Вы установили filerProcessesUrl из LogoutFilter в "/", что означает, что каждый раз, когда пользователь просматривает корень домена, фильтр будет пытаться выйти из системы. Используйте определенный URL-адрес выхода из системы (или значение по умолчанию) и проверьте, действительно ли пользователь прошел аутентификацию, прежде чем пытаться выполнить выход из системы (убедитесь, что экземпляр Authentication не равен NULL).

Если вам нужно иметь дело с таймаутами сеанса, когда пользователь не может выйти из системы, вам также нужно будет внедрить HttpSessionListener, который идентифицирует пользователя из сеанса и выполняет любую необходимую вам очистку. Это будет добавлено в ваш файл web.xml. Обратите внимание, что этот класс не вызывается во время запроса пользователя, поэтому вы не можете использовать SecurityContext для получения информации о пользователе, вы должны получить ее из объекта сеанса, который передается слушателю до того, как сеанс будет признан недействительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...