2012-08-13 16 views
41

Desidero ricevere alcune informazioni per richiesta, quindi penso che invece di avere una funzione per ogni richiesta e ottenere tali informazioni dalle richieste separatamente, è meglio avere un filtro.
Quindi ogni richiesta deve superare quel filtro e io guadagno quello che voglio.


La domanda è: come posso scrivere un filtro personalizzato?
Supponiamo che non sia come un filtro di sicurezza a molla predefinito ed è totalmente nuovo.Come scrivere un filtro personalizzato nella sicurezza di primavera?

risposta

42

È possibile utilizzare il filtro standard Java. Basta posizionarlo dopo il filtro di autenticazione in web.xml (questo significa che andrà più avanti 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> 

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</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> 

Inoltre è possibile aggiungere gestore che verrà richiamato dopo il login di successo (è necessario estendere SavedRequestAwareAuthenticationSuccessHandler). Look here come fare questo. E penso che questa sia un'idea ancora migliore.


AGGIORNAMENTO:
o si può avere questo filtro alla fine dei filtri di sicurezza in questo modo:

<security:filter-chain-map> 
    <sec:filter-chain pattern="/**" 
      filters=" 
     ConcurrentSessionFilterAdmin, 
     securityContextPersistenceFilter, 
     logoutFilterAdmin, 
     usernamePasswordAuthenticationFilterAdmin, 
     basicAuthenticationFilterAdmin, 
     requestCacheAwareFilter, 
     securityContextHolderAwareRequestFilter, 
     anonymousAuthenticationFilter, 
     sessionManagementFilterAdmin, 
     exceptionTranslationFilter, 
     filterSecurityInterceptorAdmin, 
     MonitoringFilter"/> <!-- Your Filter at the End --> 
</security:filter-chain-map> 

E per avere il filtro, è possibile utilizzare questo:

public class MonitoringFilter extends GenericFilterBean{ 
@Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 
    //Implement this Function to have your filter working 
} 
+0

Mentre stavo aspettando la risposta, mi si avvicinò con una soluzione. Ho aggiunto il mio filtro (esteso 'GenericFilterBean') alla fine dei miei filtri di sicurezza. Funziona bene. Ma ora, come ho visto la tua risposta, suona meglio per me. Sto dando una prova alla tua soluzione. Spero che funzioni anche. Ti farò sapere il risultato. Grazie. –

+0

Generalmente la tua risposta è corretta, ma devo modificarla un po '. Grazie per l'aiuto. –

+0

Ok. Modifica il mio annullamento e accetterò le tue modifiche. Sarà interessante per me sapere dove ho sbagliato. – dimas

13

Solo gettandolo nel mix; come circa usando custom-filter all'interno http elemento:

<security:http auto-config="false" ...> 
    ... 
    <security:custom-filter position="FORM_LOGIN_FILTER" ref="MyCustomFilter" /> 
</security:http> 
+1

Questa è di gran lunga la soluzione migliore. Volevo eseguire il mio filtro prima di tutto il resto:

Problemi correlati