2012-08-13 2 views
41

Ich möchte einige Informationen pro Anfrage erhalten, so denke ich, anstatt eine Funktion für jede Anfrage zu haben und diese Informationen von Anfragen getrennt zu erhalten, ist es besser, einen Filter zu haben.
Also jede Anfrage soll diesen Filter passieren und ich bekomme, was ich will.


Die Frage ist: Wie kann ich einen benutzerdefinierten Filter schreiben?
Angenommen, es ist nicht wie ein vordefinierter Frühling Sicherheitsfilter und es ist völlig neu.Wie schreibe ich einen benutzerdefinierten Filter im Frühjahr Sicherheit?

Antwort

42

Sie können den Standard-Java-Filter verwenden. Platziere es einfach nach dem Authentifizierungsfilter in web.xml (das bedeutet, dass es später in die Filterkette geht und nach der Sicherheitsfilterkette aufgerufen wird).

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 
    } 

} 

Fragment von 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> 

Sie können auch Handler hinzufügen, die nach erfolgreichem Login aufgerufen werden (Sie müssen SavedRequestAwareAuthenticationSuccessHandler verlängern). Look here wie man das macht. Und ich denke, das ist eine noch bessere Idee.


AKTUALISIERT:
Oder Sie können am Ende Ihrer Sicherheits Filter wie folgt diesen Filter haben:

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

Und Ihre Filter haben, können Sie diese verwenden:

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

Als ich für die Antwort wartete, kam ich mit einer Lösung auf. Ich habe meinen Filter (erweitert 'GenericFilterBean') am Ende meiner Sicherheitsfilter hinzugefügt. Es funktioniert gut. Aber jetzt, als ich deine Antwort sah, klingt es besser für mich. Ich versuche deine Lösung. Hoffe es geht auch. Ich werde Sie das Ergebnis wissen lassen. Vielen Dank. –

+0

Im Allgemeinen ist Ihre Antwort korrekt, aber ich muss sie etwas ändern. Danke für Ihre Hilfe. –

+0

Ok. Ändere mein Passwort und ich akzeptiere deine Änderungen. Es wird interessant für mich zu wissen, wo ich falsch lag. – dimas

13

Nur werfen dies in die Mischung; wie etwa custom-filter innen http Element mit:

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

Dies ist bei weitem die beste Lösung. Ich wollte meinen eigenen Filter vor allem anderen ausführen: