Spring Security sans web.XML

Quelle est la façon recommandée d'ajouter la sécurité du ressort à une application web qui utilise le nouveau WebApplicationInitializer interface au lieu du web.fichier xml? Je suis à la recherche de l'équivalent de:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

UPDATE

Les réponses sont raisonnables, mais ils supposent que j'ai un servletContext instance. J'ai regardé à travers la hiérarchie de WebApplicationInitializers et je ne vois pas l'accès à la servlet contexte, à moins que je choisis pour remplacer l'un de Printemps initialiseur de méthodes. AbstractDispatcherServletInitializer.registerServletFilter semble être le choix judicieux, mais il n'est pas par défaut à la cartographie des modèles D'URL et je détesterais changer l'enregistrement de filtre pour tout s'il y a une meilleure façon.

19
demandé sur Jeff 2013-01-08 02:24:14

7 réponses

Voici comment je l'ai fait:

container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
                    .addMappingForUrlPatterns(null, false, "/*");

conteneur est une instance de ServletContext

26
répondu Biju Kunjummen 2013-01-07 22:42:44

Référence De Sécurité Du Printemps répond à cette question et la solution dépend de si oui ou non vous utilisez la sécurité du ressort en conjonction avec le ressort ou le ressort MVC.

utilisation de la sécurité du ressort sans ressort ni ressort MVC

Si vous utilisation de la sécurité du ressort avec ressort ou ressort MVC (i.e. vous n'avez pas de WebApplicationInitializer) alors vous devez fournir la classe supplémentaire suivante:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SecurityConfig.class);
    }
}

SecurityConfig est votre classe de configuration Java de sécurité du printemps.

utilisation de la sécurité à ressort avec ressort ou ressort MVC

si vous utilisez Spring Security avec Spring ou Spring MVC (i.e. vous avez un WebApplicationInitializer) ensuite, vous devez tout d'abord fournir la classe supplémentaire suivante:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {
}

ensuite, vous devez vous assurer que votre classe de configuration Java de la sécurité du printemps,SecurityConfig dans cet exemple, est déclaré dans votre MVC de printemps ou de printemps existant WebApplicationInitializer. Pour exemple:

import org.springframework.web.servlet.support.*;

public class MvcWebApplicationInitializer
    extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SecurityConfig.class};
    }

    // ... other overrides ...
}
13
répondu Mark Hobson 2015-06-17 20:58:14
Dynamic securityFilter = servletContext.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");

EnumSet.allOf (DispatcherType.classe) pour être sûr que vous ajoutez un mapping non seulement pour DispatcherType par défaut.Demande, mais pour DispatcherType.AVANCER, etc...

8
répondu Maksym Demidas 2014-08-22 13:01:53

Après un peu de travail, j'ai découvert que c'est en fait assez simple:

public class Initialiser extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {

    @Override
    protected Class< ? >[] getRootConfigClasses() {
        return new Class[] { RootConfig.class };
    }

    @Override
    protected Class< ? >[] getServletConfigClasses() {
        return new Class[] { WebAppConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain") };
    }
}

la chose La plus importante, cependant, est que vous avoir un contexte racine (par exemple RootConfig dans ce cas), et qui doit contenir une référence à toutes les informations de sécurité du ressort.

ainsi, mon RootConfig catégorie:

@ImportResource("classpath:spring/securityContext.xml")
@ComponentScan({ "com.example.authentication", "com.example.config" })
@Configuration
public class RootConfig {

    @Bean
    public DatabaseService databaseService() {
        return new DefaultDatabaseService();
    }

    @Bean
    public ExceptionMappingAuthenticationFailureHandler authExceptionMapping() {
        final ExceptionMappingAuthenticationFailureHandler emafh = new ExceptionMappingAuthenticationFailureHandler();
        emafh.setDefaultFailureUrl("/loginFailed");
        final Map<String, String> mappings = new HashMap<>();
        mappings.put(CredentialsExpiredException.class.getCanonicalName(), "/change_password");
        emafh.setExceptionMappings(mappings);
        return emafh;
    }
}

Et spring/securityContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:security="http://www.springframework.org/schema/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:noNamespaceSchemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <security:http security="none" pattern="/favicon.ico"/>

    <!-- Secured pages -->
    <security:http use-expressions="true">
        <security:intercept-url pattern="/login" access="permitAll" />
        <security:intercept-url pattern="/**" access="isAuthenticated()" />
        <security:form-login default-target-url="/index" login-processing-url="/login_form" login-page="/login" authentication-failure-handler-ref="authExceptionMapping" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider ref="customAuthProvider" />
    </security:authentication-manager>
</beans>

je ne pouvais pas le faire fonctionner, si j'ai fusionné les RootConfig et WebAppConfig classes dans WebAppConfig et a été la suivante:

@Override
protected Class< ? >[] getRootConfigClasses() {
    return null;
}

@Override
protected Class< ? >[] getServletConfigClasses() {
    return new Class[] { WebAppConfig.class };
}
3
répondu ipsi 2013-07-02 05:41:44
public class SIServerSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        Dynamic registration = servletContext.addFilter("TenantServletFilter", TenantServletFilter.class);
        EnumSet<DispatcherType> dispatcherTypes = getSecurityDispatcherTypes();
        registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
    }

}

ce scénario est pour exécuter un filtre avant d'exécuter d'autres filtres. Si vous voulez exécuter un filtre après que les autres filtres passent trueregistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");. Vérifiez également le type de DispatcherType ASYNC, FORWARD etc.

2
répondu Deepak 2015-07-09 17:06:59

Face au même problème. Fusionner RootConfig et WebAppConfig-pas de la meilleure façon - parce que cela je n'ai pas essayé cette solution. Essayé toutes les autres solutions - everty temps m'a "org.Apache.Catalina.core.StandardContext.startInternal Error filterStart". Après un peu de travail, j'ai quelque chose comme ça:

    FilterRegistration.Dynamic enc= servletContext.addFilter("encodingFilter",
            new CharacterEncodingFilter());
    encodingFilter .setInitParameter("encoding", "UTF-8");
    encodingFilter .setInitParameter("forceEncoding", "true");
    encodingFilter .addMappingForUrlPatterns(null, true, "/*");

mais ne travaille pas avec DelegatingFilterProxy(). Continuer à trouver la meilleure solution commune pour tous les filtres.

mise à jour: Je n'ai il.

ainsi, le problème principal est: si vous voulez ajouter des filtres en utilisant java config, surtout si vous voulez ajouter un filtre de sécurité, tel que DelegatingFilterProxy, alors vous devez créer WebAppSecurityConfig:

@Configuration
@EnableWebSecurity
@ImportResource("classpath:security.xml")
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
}

dans ce cas, je crée WebAppSecurityConfig et je fais importer la ressource ("security.XML.)" Cela m'a permis de le faire dans la classe Initializer:

servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
            .addMappingForUrlPatterns(null, false, "/*");
0
répondu dikkini 2014-03-18 23:14:25

ceci est lié à ceux qui s'intéressent à la botte de printemps avec la sécurité: Vous n'avez besoin de rien, la botte de printemps ramasse les @components et résout les autres problèmes

0
répondu Johnny Bigoode 2017-12-15 12:40:11