我按照http://shazsterblog.blogspot.com.es/2014/07/spring-security-custom-filterchainproxy.html上的教程使用Java配置而不是XML来创建安全过滤器。
未创建bean且应用程序无法加载:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:575)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1111)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1123)
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:323)
at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235)
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:234)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:332)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:90)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3783)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4409)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:313)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:145)
at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461)
at org.jboss.web.deployers.WebModule.startModule(WebModule.java:122)
at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
这是web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/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.config.SecurityConfig</param-value>
</context-param>
<servlet>
<servlet-name>Dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Dispatcher</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>test</realm-name>
</login-config>
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>COMUN</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
</web-app>
这是SecurityConfig
类:
@Configuration
@EnableWebMvc
public class SecurityConfig extends WebMvcConfigurerAdapter implements ResourceLoaderAware{
private ResourceLoader resourceLoader;
@Bean
public FilterChainProxy springSecurityFilterChain() throws Exception {
AuthenticationManager am = authenticationManager();
SecurityContextPersistenceFilter sif = getSecurityContextPersistenceFilter();
J2eePreAuthenticatedProcessingFilter j2eePreAuthFilter = getJ2eePreAuthenticatedProcessingFilter(am);
LogoutFilter logoutFilter = getLogoutFilter();
ExceptionTranslationFilter etf = getExceptionTranslationFilter();
FilterSecurityInterceptor fsi = getFilterSecurityInterceptor(am);
FilterChainProxy fcp = new FilterChainProxy(new DefaultSecurityFilterChain(
new AntPathRequestMatcher("/**"),
sif, j2eePreAuthFilter, logoutFilter, etf, fsi
));
return fcp;
}
private FilterSecurityInterceptor getFilterSecurityInterceptor(AuthenticationManager am) {
AccessDecisionVoter<Object> roleVoter = new RoleVoter();
List<AccessDecisionVoter> decisionVoters = new LinkedList<AccessDecisionVoter>();
decisionVoters.add(roleVoter);
AffirmativeBased httpRequestAccessDecisionManager = new AffirmativeBased(decisionVoters);
httpRequestAccessDecisionManager.setAllowIfAllAbstainDecisions(false);
FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
filterSecurityInterceptor.setAuthenticationManager(am);
filterSecurityInterceptor.setAccessDecisionManager(httpRequestAccessDecisionManager);
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();
List<ConfigAttribute> configs = new ArrayList<ConfigAttribute>();
configs.add(new org.springframework.security.access.SecurityConfig("hasRole(ADMIN)"));
requestMap.put(new AntPathRequestMatcher("/**"), configs);
FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource = new ExpressionBasedFilterInvocationSecurityMetadataSource(
requestMap, new DefaultWebSecurityExpressionHandler());
filterSecurityInterceptor
.setSecurityMetadataSource(filterInvocationSecurityMetadataSource);
return filterSecurityInterceptor;
}
private LogoutFilter getLogoutFilter() {
org.springframework.security.web.authentication.logout.LogoutFilter logoutFilter = new LogoutFilter("/", new SecurityContextLogoutHandler());
return logoutFilter;
}
private ExceptionTranslationFilter getExceptionTranslationFilter() {
ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(
new Http403ForbiddenEntryPoint());
return exceptionTranslationFilter;
}
private SecurityContextPersistenceFilter getSecurityContextPersistenceFilter() {
return new org.springframework.security.web.context.SecurityContextPersistenceFilter();
}
private J2eePreAuthenticatedProcessingFilter getJ2eePreAuthenticatedProcessingFilter(AuthenticationManager am) throws Exception {
WebXmlMappableAttributesRetriever mappableRolesRetriever = new WebXmlMappableAttributesRetriever();
mappableRolesRetriever.setResourceLoader(this.resourceLoader);
mappableRolesRetriever.afterPropertiesSet();
SimpleAttributes2GrantedAuthoritiesMapper userRoles2GrantedAuthoritiesMapper = new SimpleAttributes2GrantedAuthoritiesMapper();
userRoles2GrantedAuthoritiesMapper.setConvertAttributeToUpperCase(true);
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
= new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource.setMappableRolesRetriever(mappableRolesRetriever);
j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource.setUserRoles2GrantedAuthoritiesMapper(userRoles2GrantedAuthoritiesMapper);
J2eePreAuthenticatedProcessingFilter j2eePreAuthenticatedProcessingFilter = new J2eePreAuthenticatedProcessingFilter();
j2eePreAuthenticatedProcessingFilter.setAuthenticationManager(am);
j2eePreAuthenticatedProcessingFilter.setAuthenticationDetailsSource(j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource);
return j2eePreAuthenticatedProcessingFilter;
}
@Bean
public AuthenticationManager authenticationManager() throws Exception {
PreAuthenticatedGrantedAuthoritiesUserDetailsService preAuthenticatedGrantedAuthoritiesUserDetailsService = new PreAuthenticatedGrantedAuthoritiesUserDetailsService();;
PreAuthenticatedAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthenticatedAuthenticationProvider();
preAuthenticatedAuthenticationProvider.setPreAuthenticatedUserDetailsService(preAuthenticatedGrantedAuthoritiesUserDetailsService);
List<AuthenticationProvider> lProviders = new LinkedList<AuthenticationProvider>();
lProviders.add(preAuthenticatedAuthenticationProvider);
AuthenticationManager am = new ProviderManager(lProviders);
return am;
}
@Override
public void setResourceLoader(ResourceLoader arg0) {
this.resourceLoader = arg0;
}
}
请帮忙吗?
答案 0 :(得分:0)
与示例有点不同,在这种情况下简化了,如果在component-scan上设置了包,则会创建过滤器类
web.xml的以下部分不需要:
<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.config.SecurityConfig</param-value>
</context-param>
web.xml定义了应用程序上下文,它将扫描类并创建过滤器的实例。稍后,该实例将在web.xml中使用
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/application-context-${environment}.xml</param-value>
</context-param>
如果$ {environment}变量是“DEV”,它使用具有XML定义的安全性的应用程序上下文,如果$ {environment}变量是“PRO”,它使用具有逻辑的以下应用程序上下文在Java中定义:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd>
<context:component-scan base-package="com.config" />
</beans>
过滤器只需要在PRO中创建,因此它只需要在PRO中使用的应用程序上下文中对其包进行组件扫描。