Подтвердить что ты не робот

Spring Безопасность без web.xml

Каков рекомендуемый способ добавления Spring Безопасность в веб-приложение, использующее Spring новый WebApplicationInitializer интерфейс вместо файла web.xml? Я ищу эквивалент:

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

ОБНОВЛЕНИЕ
Предоставленные ответы являются разумными, но оба они предполагают, что у меня есть экземпляр servletContext. Я просмотрел иерархию WebApplicationInitializer, и я не вижу никакого доступа к контексту сервлета, если я не решил переопределить один из методов инициализации Spring. AbstractDispatcherServletInitializer.registerServletFilter кажется разумным выбором, но он не по умолчанию не отображает шаблон URL, и я бы не хотел менять регистрацию фильтра для всего, если есть лучший способ.

4b9b3361

Ответ 1

Вот так я это сделал:

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

контейнер - это экземпляр ServletContext

Ответ 2

Spring Ссылка на безопасность отвечает на этот вопрос, и решение зависит от того, используете ли вы Spring Security в сочетании с Spring или Spring MVC.

Использование Spring Безопасность без Spring или Spring MVC

Если вы не, используя Spring Безопасность с Spring или Spring MVC (т.е. у вас нет существующего WebApplicationInitializer), вам необходимо предоставить следующий дополнительный класс:

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

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

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

Где SecurityConfig - ваш Spring класс конфигурации безопасности Java.

Использование Spring Безопасность с Spring или Spring MVC

Если вы используете Spring Безопасность с Spring или Spring MVC (т.е. у вас есть существующий WebApplicationInitializer), то сначала вам необходимо предоставить следующий дополнительный класс:

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

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {
}

Затем вам нужно убедиться, что ваш класс конфигурации Spring Security Java, SecurityConfig в этом примере объявлен в вашем существующем Spring или Spring MVC WebApplicationInitializer. Например:

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

public class MvcWebApplicationInitializer
    extends AbstractAnnotationConfigDispatcherServletInitializer {

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

    // ... other overrides ...
}

Ответ 3

Dynamic securityFilter = servletContext.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");

EnumSet.allOf(DispatcherType.class), чтобы добавить сопоставление не только по умолчанию DispatcherType.REQUEST, но и для DispatcherType.FORWARD и т.д..

Ответ 4

После небольшой работы я обнаружил, что это на самом деле довольно просто:

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") };
    }
}

Самое главное, однако, что вы должны иметь корневой контекст (например, RootConfig в этом случае) и должны содержать ссылку на всю информацию о безопасности spring.

Таким образом, мой класс RootConfig:

@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;
    }
}

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

Я не мог заставить его работать, если я объединил классы RootConfig и WebAppConfig только WebAppConfig и имел следующее:

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

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

Ответ 5

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, "/*");
    }

}

Этот сценарий предназначен для выполнения фильтра перед выполнением других фильтров. Если вы хотите выполнить фильтр после того, как другие фильтры перейдут true в registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");. Также проверьте DispatcherType ASYNC, FORWARD и т.д.

Ответ 6

Столкнувшись с той же проблемой. Слияние RootConfig и WebAppConfig - не лучший способ - потому что я не пробовал это решение. Пробовал все другие решения - вовремя время получилось "org.apache.catalina.core.StandardContext.startInternal Error filterStart". После некоторой работы получилось что-то вроде этого:

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

Но не работает с DelegatingFilterProxy(). Продолжайте поиск наилучшего общего решения для всех фильтров.

UPDATE: Я сделал это.

Итак, основная проблема: если вы хотите добавить фильтры с помощью java config, особенно если вы хотите добавить фильтр защиты, например DelegatingFilterProxy, то вам нужно создать WebAppSecurityConfig:

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

В этом случае я создаю WebAppSecurityConfig и создаю ресурс импорта ( "security.xml" ). Это позволило мне сделать это в классе Initializer:

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

Ответ 7

Это связано с заинтересованными в Spring загрузке с безопасностью: вам ничего не нужно, Spring Boot загружает @компоненты и решает другие проблемы