2016-07-22 56 views
0

我试图将下面的spring security java配置转换为xml配置;面向Spring Security的XML配置问题

Java config;

package com.careapple.webservice.security.config; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.HttpMethod; 
import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.config.http.SessionCreationPolicy; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.web.AuthenticationEntryPoint; 
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

import com.careapple.webservice.security.filter.AuthenticationTokenFilter; 

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@EnableTransactionManagement 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService userDetailsService; 
    @Autowired 
    private AuthenticationEntryPoint authenticationEntryPoint; 


    @Autowired 
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { 
     authenticationManagerBuilder 
       .userDetailsService(userDetailsService) 
       .passwordEncoder(new BCryptPasswordEncoder()); 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 


    @Bean 
    public AuthenticationTokenFilter authenticationTokenFilterBean() throws Exception { 
     AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter(); 
     authenticationTokenFilter.setAuthenticationManager(super.authenticationManagerBean()); 
     return authenticationTokenFilter; 
    } 


    @Override 
    protected void configure(HttpSecurity httpSecurity) throws Exception { 
     httpSecurity 
       .csrf() 
       .disable() 
       .exceptionHandling() 
       .authenticationEntryPoint(authenticationEntryPoint) 
       .and() 
       .sessionManagement() 
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
       .and() 
       .authorizeRequests() 
       .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() 
       .antMatchers("/auth/**").permitAll() 
       .anyRequest().authenticated(); 

     // Custom JWT based authentication 
     httpSecurity 
       .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); 
    } 
} 

转换后的xml配置;弹簧security.xml文件

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

    <global-method-security secured-annotations="enabled"/> 

    <http realm="Protected API" 
     create-session="stateless" 
     entry-point-ref="authenticationEntryPoint" 
     authentication-manager-ref="authenticationManager"> 

     <csrf disabled="true"/> 

     <custom-filter ref="authenticationTokenFilter" position="FORM_LOGIN_FILTER"/> 

     <intercept-url pattern="/login/**" access="permitAll"/> 
     <intercept-url pattern="/" access="isFullyAuthenticated()"/> 
    </http> 


    <bean:bean id="authenticationEntryPoint" class="com.careapple.webservice.security.EntryPointUnauthorizedHandler"/> 

    <bean:bean id="userDetailService" class="com.careapple.webservice.security.service.UserDetailsServiceImpl"/> 

    <bean:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> 

    <authentication-manager id="authenticationManager"> 
     <authentication-provider user-service-ref="userDetailService"> 
      <password-encoder ref="bcryptEncoder"></password-encoder> 
     </authentication-provider> 
    </authentication-manager> 

    <bean:bean id="authenticationTokenFilter" class="com.careapple.webservice.security.filter.AuthenticationTokenFilter" 
     c:authenticationManager-ref="authenticationManager"/> 

</bean:beans> 

我是新来的春季安全,我想第一件事是,有我转换了Java配置正确XML。或者我错过了什么。

接下来,如果我运行这个XML文件的应用程序,我收到以下错误;

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'authenticationTokenFilter' while setting constructor argument with key [3]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationTokenFilter' defined in ServletContext resource [/WEB-INF/spring-security.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities) 

其中,authenticationTokenFilter是,我使用的是自定义过滤器,它实现了Spring的UsernamePasswordAuthenticationFilter。

这是我的web.xml文件;

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

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring-security.xml</param-value> 
    </context-param> 

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

    <servlet> 
     <servlet-name>spring</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/WEB-INF/spring-servlet.xml</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>spring</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <filter> 
     <filter-name>authenticationTokenFilter</filter-name> 
     <filter-class>com.careapple.webservice.security.filter.AuthenticationTokenFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>authenticationTokenFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

</web-app> 

我想太多的东西,现在, 1.是否所有的配置XML文件是正确的。 2.如果是这样如何纠正我得到的异常。

请给出您的建议,我很长时间以来一直在努力。我提到了所有相关的stackoverflow问题,但我无法从中找到解决方案。

编辑: 这是我的AuthenticationTokenFilter;

package com.careapple.webservice.security.filter; 

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.http.HttpStatus; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.context.SecurityContextHolder; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; 
import org.springframework.web.context.support.WebApplicationContextUtils; 

import com.careapple.webservice.security.TokenUtils; 
import com.careapple.webservice.util.AppConstant; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter { 

    @Autowired 
    private TokenUtils tokenUtils; 

    @Autowired 
    private UserDetailsService userDetailsService; 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException{ 

     tokenUtils = WebApplicationContextUtils 
       .getRequiredWebApplicationContext(this.getServletContext()) 
       .getBean(TokenUtils.class); 
     userDetailsService = WebApplicationContextUtils 
       .getRequiredWebApplicationContext(this.getServletContext()) 
       .getBean(UserDetailsService.class); 

     HttpServletResponse resp = (HttpServletResponse) response; 
     resp.setHeader("Access-Control-Allow-Origin", "*"); 
     resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH"); 
     resp.setHeader("Access-Control-Max-Age", "3600"); 
     resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, " + AppConstant.tokenHeader); 


     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     String authToken = httpRequest.getHeader(AppConstant.tokenHeader); 
     System.out.println("Token: " + authToken); 
     String username = this.tokenUtils.getUsernameFromToken(authToken); 
     System.out.println("Username: " + username); 

     if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { 
      UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); 
      System.out.println("inside first if"); 
      if (this.tokenUtils.validateToken(authToken, userDetails)) { 
        UsernamePasswordAuthenticationToken authentication = 
          new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 
        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); 
        SecurityContextHolder.getContext().setAuthentication(authentication); 

      } 
     } 

      try { 
       chain.doFilter(request, response); 
      } catch (Exception e) { 
       Map<String, String> tokenExpired = new HashMap<>(); 
       tokenExpired.put("TokenExpired", "Authentication token expired, please login again"); 
       resp.setContentType("application/json"); 
       resp.setStatus(HttpStatus.FORBIDDEN.value()); 
       resp.getWriter().write(convertObjectToJson(tokenExpired)); 
      } 
    } 

    public String convertObjectToJson(Object object) throws JsonProcessingException { 
     if (object == null) { 
      return null; 
     } 
     ObjectMapper mapper = new ObjectMapper(); 
     return mapper.writeValueAsString(object); 
    } 
} 
+0

1.没有事实并非如此。 2.使您的自定义筛选器成为Spring安全筛选器链的一部分,而不是纯文件运行web.xml。此外,为什么你想要XML配置,而不是基于Java的?其他方式更常见。 –

+0

感谢您的回复,我是春季安全新手,请您告诉我们如何制作弹簧安全滤网链条的定制过滤部分。我不能够使用托管服务器的Java配置,它给了我404,这就是为什么我改变了我的配置XML生活中的应用。我甚至发布了这些问题,但无法从中获得解决方案; http://stackoverflow.com/questions/38507424/mixing-xml-and-java-config-for-spring-security – karthi

+0

http://stackoverflow.com/questions/38482009/getting-404-when-deploying-spring- mvc-web-application-live-serverarvixe – karthi

回答

0

您的自定义认证过滤器需要仅在弹簧security.xml文件中定义,看着它,它应该是罚款。

在你的web.xml,你需要删除你的过滤器(这是一个Spring Security的过滤器不是一个JavaEE的过滤器),并添加春季安全过滤器。来自Spring的错误消息是它无法找到Spring Security过滤器,从而拒绝解析pring-security.xml文件。

所以从web.xml中删除您的过滤器,并用这些行添加春季保障,一切应罚款

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

问候,

卢瓦克

+0

试过这个,但得到相同的错误。 – karthi

+0

你好,再次阅读你正面临的错误,它是基本的春天依赖注入相关:错误创建名为'authenticationTokenFilter'的bean ...无法解析匹配构造函数... 你可以分享你的AuthenticationTokenFilter的代码显然有一个问题在它的构造函数,这个类是否有一个空的构造函数? – loicmathieu

+0

我用AuthenticationTokenFilter代码编辑了我的问题。 – karthi