2015-06-07 8 views
5

(Отредактировано для пояснения) У меня есть POJO (SessionStorage) для хранения данных, относящихся к сеансу, которые я хочу заполнить после успешной проверки подлинности. Поскольку я устанавливаю Scope в «session», я ожидаю, что MainController и AuthenticationSuccesshandler будут использовать один и тот же экземпляр объекта.Настройка объектов с ограниченным доступом в AuthenticationSuccessHandler

Когда я запускаю WebApp, главный контроллер инициирует экземпляр (как и ожидалось), но при входе в систему, AuthenticationSuccesshandler, похоже, не имеет автообновления объекта SessionStorage, поскольку он генерирует исключение NullPointerException.

Как мне заставить его делать то, что я хочу? Вот выдержки из моего кода:

@Component 
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 
public class SessionStorage implements Serializable{ 
    long id; 
    public int getId() { 
    return id; 
    } 

    public SessionStorage() { 
     System.out.println("New Session Storage"); 
     id = System.currentTimeMillis(); 
    } 
} 

Главный контроллер выглядит следующим образом:

@Controller 
@Scope("request") 
@RequestMapping("/") 
public class MainController { 
    @Autowired 
    private SessionStorage sessionStorage; 

    @RequestMapping(value = "/login", method = RequestMethod.GET) 
    public ModelAndView login(
      @RequestParam(value = "error", required = false) String error, 
      @RequestParam(value = "logout", required = false) String logout) { 

     System.out.println(sessionStorage.getId()); //Works fine 

     ModelAndView model = new ModelAndView(); 
     if (error != null) { 
      model.addObject("error", "Invalid username and  password!"); 
     } 

     if (logout != null) { 
      model.addObject("msg", "You've been logged out successfully."); 
     } 
     model.setViewName("login"); 
     return model; 
    } 
} 

AuthentificationSuccesshandler (где брошено ошибка):

public class AuthentificationSuccessHandler implements AuthenticationSuccessHandler { 

    @Autowired 
    private SessionStorage sessionStorage; 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest hsr, HttpServletResponse hsr1, Authentication a) throws IOException, ServletException { 
     System.out.println("Authentication successful: " + a.getName()); 
     System.out.println(sessionStorage.getId()); //NullPointerException 
    } 
} 

Соответствующая часть spring-security.xml:

<beans:bean id="authentificationFailureHandler" class="service.AuthentificationFailureHandler" /> 
    <beans:bean id="authentificationSuccessHandler" class="service.AuthentificationSuccessHandler" /> 
    <http auto-config="true" use-expressions="true"> 
     <intercept-url pattern="/secure/**" access="hasRole('USER')" /> 


     <form-login 
      login-page="/login" 
      default-target-url="/index" 
      authentication-failure-handler-ref="authentificationFailureHandler" 
      authentication-failure-url="/login?error" 
      authentication-success-handler-ref="authentificationSuccessHandler" 
      username-parameter="username" 
      password-parameter="password" /> 
     <logout logout-success-url="/login?logout" /> 
     <!-- enable csrf protection --> 
     <csrf/> 
    </http> 

веб-XML:

<listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
+0

Я понимаю, что это старый вопрос, но я бегу в том же номере, и было интересно, если вы пришли с решением? – lastmannorth

ответ

2

Этот вопрос старый, но показал, как один из первых ссылок на мой вопрос в Google.

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

@Component 
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS) 

Более подробную информацию можно найти здесь: https://tuhrig.de/making-a-spring-bean-session-scoped/

Смежные вопросы