2012-07-05 6 views
6

Sono un novizio di Spring Security 3. Uso i ruoli per gli utenti per l'accesso.Come aggiungere un filtro personalizzato dopo che l'utente ha autorizzato l'applicazione in primavera

Desidero aggiungere un valore di sessione dopo che un utente è autorizzato nell'applicazione. Forse ho bisogno di un filtro per reindirizzare al mio metodo che aggiunge qualche valore di sessione. Ho configurato il mio file security.xml ma non sono sicuro di fare le cose giuste. Qualsiasi esempio in quella direzione sarebbe d'aiuto. Quale classe filtro dovrei usare? Come dovrei configurare il file security.xml?

<custom-filter ref="authenticationFilter" after="FORM_LOGIN_FILTER "/> 

<beans:bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
    <beans:property name="filterProcessesUrl" value="/j_spring_security_check" /> 
    <beans:property name="authenticationManager" ref="authenticationManager" /> 
    <beans:property name="authenticationSuccessHandler" ref="successHandler" /> 
</beans:bean> 

<beans:bean id="successHandler" class="org.dfci.sparks.datarequest.security.CustomAuthorizationFilter"/> 

Il mio metodo di classe filtro Ho bisogno di aggiungere qualche valore di sessione.

public class CustomAuthorizationFilter implements AuthenticationSuccessHandler { 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest request, 
      HttpServletResponse response, Authentication authentication) 
      throws IOException, ServletException { 
     Set<String> roles = AuthorityUtils.authorityListToSet(authentication 
       .getAuthorities()); 
     if (roles.contains("ROLE_USER")) { 
      request.getSession().setAttribute("myVale", "myvalue"); 
     } 
    } 
} 

Modifica codice

Ho modificato il mio file security.xml e file di classe

<custom-filter ref="authenticationFilter" after="FORM_LOGIN_FILTER "/> 
public class CustomAuthorizationFilter extends GenericFilterBean { 

    /* 
    * ServletRequestAttributes attr = (ServletRequestAttributes) 
    * RequestContextHolder.currentRequestAttributes(); HttpSession 
    * session=attr.getRequest().getSession(true); 
    */ 
    @Autowired 
    private UserService userService; 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException { 

     try { 
      chain.doFilter(request, response); 

        HttpServletRequest req = (HttpServletRequest) request; 
        HttpSession session = req.getSession(true); 
        Authentication authentication = SecurityContextHolder 
          .getContext().getAuthentication(); 
        Set<String> roles = AuthorityUtils 
          .authorityListToSet(authentication.getAuthorities()); 
        User user = null;     
         if (true) { 
          session.setAttribute("Flag", "Y"); 
         } 
      } 

     } catch (IOException ex) { 
      throw ex; 
     } 
    } 

} 

che richiama ogni URL. C'è qualche alternativa a chiamare il metodo di filtraggio solo una volta quando un utente è autenticato?

+0

Qual è il problema con il codice sopra? Non ricevi l'attributo myValue di sessione all'interno dell'url di login? –

+0

@SunilChavan: chiama questo filtro prima che l'utente sia autenticato. – Raje

+0

Come puoi dire questo? Consulta i dettagli (API) [http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/authentication/AuthenticationSuccessHandler.html]. Dice chiaramente dopo l'autenticazione di successo chiama su metodo Autenticazione Successo –

risposta

8

Finalmente sono stato in grado di risolvere il mio problema. Invece di usare il filtro ho aggiunto un gestore che invoca solo per il login riuscito.

Seguendo la linea viene aggiunto in security.xml

<form-login login-page="/" authentication-failure-url="/?login_error=1" default-target-url="/" always-use-default-target="false" 
     authentication-success-handler-ref="authenticationSuccessHandler"/> 
     <logout /> 

<beans:bean id="authenticationSuccessHandler" class="security.CustomSuccessHandler"/> 

Inoltre ho aggiunto gestore una consuetudine che aggiungere l'attributo sessione.

package security; 

import java.io.IOException; 
import java.security.GeneralSecurityException; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 

public class CustomSuccessHandler extends 
      SavedRequestAwareAuthenticationSuccessHandler { 
    @Override 
    public void onAuthenticationSuccess(final HttpServletRequest request, 
      final HttpServletResponse response, final Authentication authentication) 
      throws IOException, ServletException { 
     super.onAuthenticationSuccess(request, response, authentication); 

     HttpSession session = request.getSession(true); 

     try { 
      if (CurrentUser.isUserInRole("USER")) { 
       session.setAttribute("Flag", "user"); 
      } 
     } catch (Exception e) { 
      logger.error("Error in getting User()", e); 
     } 
    } 

} 
+0

sto chiamando una funzione comune da hear, ma restituisce un'eccezione di puntatore nullo che esegue jdbctemplate. – Zigri2612

+0

l'exce. Threadpoolexecutor fonte sconosciuta – Zigri2612

0

È possibile utilizzare il filtro java standard (intendo l'interfaccia di filtro dell'attrezzo). Basta posizionarlo dopo il filtro di autenticazione in web.xml (questo significa che verrà inserito più tardi nella catena di filtri e verrà chiamato dopo la catena di filtri di sicurezza).

public class CustomFilter implements Filter{ 

    @Override 
    public void destroy() { 
     // Do nothing 
    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, 
      FilterChain chain) throws IOException, ServletException { 

      HttpServletRequest request = (HttpServletRequest) req; 

      Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 

      Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities()); 
      if (roles.contains("ROLE_USER")) { 
       request.getSession().setAttribute("myVale", "myvalue"); 
      } 

      chain.doFilter(req, res); 

    } 

    @Override 
    public void init(FilterConfig arg0) throws ServletException { 
     // Do nothing 
    } 

} 

Frammento di web.xml:

<!-- The Spring Security Filter Chain --> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<!-- Pay attention to the url-pattern --> 
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
    <!-- <dispatcher>FORWARD</dispatcher> 
<dispatcher>REQUEST</dispatcher> --> 
</filter-mapping> 

<!-- Your filter definition --> 
<filter> 
    <filter-name>customFilter</filter-name> 
    <filter-class>com.yourcompany.test.CustomFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>customFilter</filter-name> 
    <url-pattern>/VacationsManager.jsp</url-pattern> 
</filter-mapping> 
+0

Modifica esempio per il tuo caso. – dimas

+0

Grazie per aver dato un esempio. Seguo gli stessi passi che hai menzionato. Ho modificato il mio codice ma quel metodo di filtro chiama per ogni URL. C'è qualche alternativa a chiamare una sola volta quando l'utente è autenticato? – Raje

+0

Se ho capito che è corretto, è necessario impostare il modello di URL corretto per il filtro (ad esempio la pagina di accesso /login.jsp). In tal caso il filtro intercetterà solo la richiesta per la tua pagina di accesso. Per gli altri URL il filtro non verrà eseguito. – dimas

Problemi correlati