Вопрос по spring-security, java, spring – Ссылка на конфигурацию Spring Security в Spring 3.1 Java Config

4

Недавно я переключил большую часть своей конфигурации Spring на использование конфигурации на основе кода в Spring 3.1. Однако теперь, когда я переключился, мой Spring Security работает неправильно и выдает следующую ошибку при запуске Tomcat:

SEVERE: Exception starting filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named     'springSecurityFilterChain' is defined

У меня все еще есть Spring Security в XML-файле, и я знаю, что его нельзя преобразовать в конфигурацию Java в Spring, поскольку это пользовательское пространство имен, однако я ссылаюсь на него в своем конфигурационном файле Java. Я также безуспешно пытался переместить ссылку на конфигурацию applicationContext-security.xml из конфигурации Java в мой файл web.xml.

@Configuration
@EnableWebMvc
@Import(ServicesConfig.class)
@ImportResource({ "classpath:applicationContext-security.xml",
"classpath:dataSources.xml" })
@ComponentScan(basePackages = "com.foobar")
public class WebConfig {
   // left out Beans for clarity
}

ApplicationContext-security.xml:

<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
xmlns:oauth2="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-3.1.xsd
      http://www.springframework.org/schema/security/oauth2
      http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

<!-- Security configuration -->

<global-method-security pre-post-annotations="enabled" />

<http use-expressions="true" access-denied-page="/error/accessDenied" 
        entry-point-ref="casEntryPoint">
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <custom-filter position="CAS_FILTER" ref="casFilter" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="casAuthenticationProvider" />
</authentication-manager>

<!-- Bean definitions -->
<b:bean id="casAuthenticationProvider"
    class="org.springframework.security.cas.authentication.CasAuthenticationProvider"
    p:serviceProperties-ref="serviceProperties" p:key="1234"
    p:authenticationUserDetailsService-ref="userDetailsByNameServiceWrapper"
    p:ticketValidator-ref="cas20ServiceTicketValidator" />

<b:bean id="userDetailsByNameServiceWrapper"
    class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"
    c:userDetailsService-ref="userDetailsService" />

<b:bean id="userDetailsService" class="foobar.MyUserDetailsService" />

<b:bean id="cas20ServiceTicketValidator" 
    class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"
    c:casServerUrlPrefix="https://mycasserver/cas" />

<b:bean id="casFilter"
    class="org.springframework.security.cas.web.CasAuthenticationFilter"
    p:authenticationManager-ref="authenticationManager" />

<b:bean id="casEntryPoint"
    class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"
    p:loginUrl="https://mycasserver/cas/login" 
    p:serviceProperties-ref="serviceProperties" />

<b:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"
    p:service="https://foobar.com/services/j_spring_cas_security_check"
    p:sendRenew="false" />

</b:beans>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<description>My App</description>

<!-- Context Params -->
<context-param>
    <param-name>contextClass</param-name>
    <param-value>
         org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    </param-value>
</context-param>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>foobar.WebConfig</param-value>
</context-param>

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

<!-- Listeners -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Servlets -->
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
         </param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>
Я обновил свой ответ конкретным примером alexkasko
Я нашел эту ссылку, чтобы быть действительно хорошим. Он объясняет, что каждый бин находится за пространством имен безопасностиstatic.springsource.org/spring-security/site/docs/3.1.x/… jasop

Ваш Ответ

4   ответа
0

ять класс DelegatingFilterProxy и называть его SpringSecurityFilterChain.

public class ServiceInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

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

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

@Override
protected Filter[] getServletFilters() {
    return new Filter[] { new OpenEntityManagerInViewFilter(), new SpringSecurityFilterChain() };
}

public class SpringSecurityFilterChain extends DelegatingFilterProxy {

}

}

Интересно, почему вы отвергаете все эти методы? У вас есть более полный пример кода? Я борюсь с настройкой безопасности только с помощью JavaConfig.
7

кто все еще ищет способ использовать конфигурацию SpringSecurity XML с веб-приложением конфигурации Java. Я получил это с помощью Spring 3.2.0.RELEASE и SpringSecurity 3.2.0.M1. Вот важные части решения

WebAppConfig.java

package com.foo.webapp;

@Configuration
@ComponentScan(basePackages = { "com.foo" })
@ImportResource(value = { "/WEB-INF/spring-security.xml" })
public class WebAppConfig {
    // other beans go here
}

весна-security.xml
Note that I had to remove the default xmlns="..." from the <beans:beans> definition.

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

    <security:http auto-config="true">
        <security:intercept-url pattern="/secured/**" access="ROLE_USER" />
        <security:form-login login-page="/login" default-target-url="/main"
                authentication-failure-url="/loginfailed" />
        <security:logout logout-success-url="/logout" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="user" authorities="ROLE_USER" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans:beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd">

    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.foo.webapp.WebAppConfig</param-value>
    </context-param>

    <!-- Spring Security -->
    <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>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>foo</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>foo</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
Я попробовал это и застрял из-за зависимостей между конфигурацией java и файлом XML. Что может зависеть от чего здесь? Правильно ли я считаю, что конфигурация XML должна быть автономной, и конфигурация java может ее использовать?
Попробуйте & quot; classpath: spring-security.xml & quot; - меньше специфичных для WEB-INF ...
1

lterChain, когда используется конфигурация Java Spring. Поскольку я работал над тем, чтобы применить эти подсказки для исправления сравнимой ошибки в моем собственном коде, я отметил, что документация Spring для org.springframework.web.WebApplicationInitializer (интерфейс, реализованный AbstractAnnotationConfigDispatcherServletInitializer) имеет следующие соответствующие значения: Caveat & quot;

web.xml versioning

Использование WEB-INF / web.xml и WebApplicationInitializer не являются взаимоисключающими; например, web.xml может зарегистрировать один сервлет, а WebApplicationInitializer может зарегистрировать другой. Инициализатор может даже изменять регистрации, выполняемые в web.xml, с помощью таких методов, как ServletContext.getServletRegistration (String).

However, if WEB-INF/web.xml is present in the application, its version attribute must be set to "3.0" or greater, otherwise ServletContainerInitializer bootstrapping will be ignored by the servlet container.

Я отмечаю это, потому что заметил, что ваша версия web.xml, отмеченная выше, все еще 2.5.

8

Не использоватьsecurity ярлыки пространства имен и перенести всю конфигурацию Spring из XML в Java. Это значительно облегчит настройку вашей безопасности. Я собираюсь сделать это для нашего проекта вскоре после перехода на 3.1. Вы можете найти нетривиальный пример конфигурации XML для простого бинаВот.

edit: Готовый конфиг (ссылка выше) миграции. Все конфиги были намеренно объединены в один метод, чтобы сделать его короче и продемонстрировать, что вам не нужно отдельного подпружиненного компонента для каждого фильтра. Конечно, лучше перемещать сложные части инициализации в отдельные методы (отмечены@Bean если необходимо). Вы можете найти рабочий пример вX509AnnotationTest.Config по ссылке выше.

@Bean
public FilterChainProxy springSecurityFilterChain() throws Exception {
    // AuthenticationEntryPoint
    BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
    entryPoint.setRealmName("AppName Realm");
    // accessDecisionManager
    List<AccessDecisionVoter> voters = Arrays.<AccessDecisionVoter>asList(new RoleVoter(), new WebExpressionVoter());
    AccessDecisionManager accessDecisionManager = new AffirmativeBased(voters);
    // SecurityExpressionHandler
    SecurityExpressionHandler<FilterInvocation> securityExpressionHandler = new DefaultWebSecurityExpressionHandler();
    // AuthenticationUserDetailsService
    UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> authenticationUserDetailsService = new UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken>(authUserDetailService);
    authenticationUserDetailsService.afterPropertiesSet();
    // PreAuthenticatedAuthenticationProvider
    PreAuthenticatedAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthenticatedAuthenticationProvider();
    preAuthenticatedAuthenticationProvider.setPreAuthenticatedUserDetailsService(authenticationUserDetailsService);
    preAuthenticatedAuthenticationProvider.afterPropertiesSet();
    // AuthenticationManager
    List<AuthenticationProvider> providers = Arrays.<AuthenticationProvider>asList(preAuthenticatedAuthenticationProvider);
    AuthenticationManager authenticationManager = new ProviderManager(providers);
    // HttpSessionSecurityContextRepository
    HttpSessionSecurityContextRepository httpSessionSecurityContextRepository = new HttpSessionSecurityContextRepository();
    // SessionRegistry
    SessionRegistry sessionRegistry = new SessionRegistryImpl();
    // ConcurrentSessionControlStrategy
    ConcurrentSessionControlStrategy concurrentSessionControlStrategy = new ConcurrentSessionControlStrategy(sessionRegistry);

    // ConcurrentSessionFilter
    ConcurrentSessionFilter concurrentSessionFilter = new ConcurrentSessionFilter(sessionRegistry);
    concurrentSessionFilter.afterPropertiesSet();
    // SecurityContextPersistenceFilter
    SecurityContextPersistenceFilter securityContextPersistenceFilter = new SecurityContextPersistenceFilter(httpSessionSecurityContextRepository);
    // X509AuthenticationFilter
    X509AuthenticationFilter x509AuthenticationFilter = new X509AuthenticationFilter();
    x509AuthenticationFilter.setAuthenticationManager(authenticationManager);
    x509AuthenticationFilter.afterPropertiesSet();
    // RequestCacheAwareFilter
    RequestCacheAwareFilter requestCacheAwareFilter = new RequestCacheAwareFilter();
    // SecurityContextHolderAwareRequestFilter
    SecurityContextHolderAwareRequestFilter securityContextHolderAwareRequestFilter = new SecurityContextHolderAwareRequestFilter();
    // SessionManagementFilter
    SessionManagementFilter sessionManagementFilter = new SessionManagementFilter(httpSessionSecurityContextRepository, concurrentSessionControlStrategy);
    // ExceptionTranslationFilter
    ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(entryPoint);
    exceptionTranslationFilter.setAccessDeniedHandler(new AccessDeniedHandlerImpl());
    exceptionTranslationFilter.afterPropertiesSet();
    // FilterSecurityInterceptor
    FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
    filterSecurityInterceptor.setAuthenticationManager(authenticationManager);
    filterSecurityInterceptor.setAccessDecisionManager(accessDecisionManager);
    LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> map = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();
    map.put(new AntPathRequestMatcher("/**"), Arrays.<ConfigAttribute>asList(new SecurityConfig("isAuthenticated()")));
    ExpressionBasedFilterInvocationSecurityMetadataSource ms = new ExpressionBasedFilterInvocationSecurityMetadataSource(map, securityExpressionHandler);
    filterSecurityInterceptor.setSecurityMetadataSource(ms);
    filterSecurityInterceptor.afterPropertiesSet();
    // SecurityFilterChain
    SecurityFilterChain chain = new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"),
            concurrentSessionFilter,
            securityContextPersistenceFilter,
            x509AuthenticationFilter,
            requestCacheAwareFilter,
            securityContextHolderAwareRequestFilter,
            sessionManagementFilter,
            exceptionTranslationFilter,
            filterSecurityInterceptor);
    return new FilterChainProxy(chain);
}
Это означает, что вообще нет никакой конфигурации web.xml?
Ссылка на примеры конфигурации безопасности XML была действительно полезной
Если вы не используетеsecurity.xmlкак вы устанавливаете<global-method-security pre-post-annotations="enabled" /> используя только Java?
Итак, как отмечается в исходной публикации, пользовательская конфигурация Spring Security должна оставаться в XML (до тех пор, пока команда Spring не сможет это изменить). Однако я не думаю, что возвращение к простым бинам является ответом - это сведет на нет все усовершенствования и упрощения, которые представило пользовательское пространство имен, и в результате вы получите гораздо менее читаемую конфигурацию безопасности. Вместо этого можно сохранить XML-конфигурацию, которая проста и понятна, и устранить исходную ошибку.
Вы берете на себя некоторые свободы"simple and to the point", Весенняя безопасность сложна, независимо от того, как ее нарезать. Я использую XML и вижу выгоду, но все это волшебное пространство имен XML (пользовательские фабрики) делает вещи за кулисами ... трудно понять, что происходит. Просто заказать фильтры довольно запутанно.

Похожие вопросы