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 WebApplicationInitializer
s 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.
7 réponses
Voici comment je l'ai fait:
container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
conteneur est une instance de ServletContext
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);
}
}
Où 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 ...
}
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...
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 };
}
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 true
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
. Vérifiez également le type de DispatcherType ASYNC, FORWARD etc.
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, "/*");
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