2015-06-07 27 views
5

(Edytowane w celu wyjaśnienia) Mam POJO (SessionStorage) do przechowywania danych specyficznych dla sesji, które chcę wypełnić po pomyślnym uwierzytelnieniu. Ponieważ ustawiam zakres na "sesję", oczekuję, że MainController i AuthenticationSuccesshandler będą używać tego samego wystąpienia obiektu.Ustawianie obiektów o zasięgu sesji w AuthenticationSuccessHandler

Po uruchomieniu WebApp kontroler główny inicjuje instancję (zgodnie z oczekiwaniami), ale kiedy się loguję, operacja AuthenticationSuccesshandler wydaje się nie mieć autopromocjonowanego obiektu SessionStorage, ponieważ generuje wyjątek NullPointerException.

Jak mogę zrobić to, czego chcę? Oto fragmenty z mojego kodu:

@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(); 
    } 
} 

Główny kontroler wygląda następująco:

@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 (gdzie błąd zostanie rzucony):

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 
    } 
} 

Istotna część 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> 

web-xml:

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

Zdaję sobie sprawę, że jest to stare pytanie, ale biegnę do tej samej kwestii i zastanawiałem się, czy ty wymyślił rozwiązanie? – lastmannorth

Odpowiedz

2

To pytanie jest stary, ale pojawił się jako jeden z pierwszych linków na moje pytanie w Google.

Poprawiono, że znalazłem najlepiej pracował, aby ustawić zakres na niestandardowy AuthenticationSuccessHandler.

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

Dalsze szczegóły można znaleźć tutaj: https://tuhrig.de/making-a-spring-bean-session-scoped/