我试图将以下spring security java配置转换为xml配置;
Java配置;
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 :(得分:0)
您的自定义身份验证过滤器只需要在spring-security.xml文件中定义,查看它,它应该没问题。
在您的web.xml上,您需要删除过滤器(它是Spring Security过滤器而不是JavaEE过滤器)并添加spring安全过滤器。 Spring的错误消息是它无法找到Spring Security过滤器,从而拒绝解析pring-security.xml文件。
所以从web.xml中删除你的过滤器,并用这些行添加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>
此致
卢瓦克