在我的spring-boot应用程序(这是一个基本的Rest API)中,我必须管理两种身份验证:
我实现了分别实现每个用例的功能,但是我无法使用这两个过滤器进行这样的配置。 我在控制器上使用Pre / PostAuthorize注释,因为某些方法受到限制,而其他方法则允许所有人使用,而无需任何令牌或basicAuth + uid
这是我的安全配置:
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
locationManager = nil
}
TokenFilter:
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userConnector;
@Autowired
private TokenEncoder tokenEncoder;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/").permitAll().and()
.authorizeRequests().antMatchers("/console/**").permitAll();
httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();
httpSecurity.addFilterAfter(basicAuthFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(tokenFilter(), BasicAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(myExceptionHandler())
.accessDeniedHandler(myExceptionHandler());
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider
= new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
return authProvider;
}
@Bean
public BasicAuthorizationFilter basicAuthFilter() {
return new BasicAuthorizationFilter();
}
@Bean
public MyTokenAuthorizationFilter tokenFilter() {
return new MyTokenAuthorizationFilter(tokenEncoder);
}
@Bean
public MyExceptionHandler myExceptionHandler() {
return new MyExceptionHandler();
}
@Override
@Bean
public UserDetailsService userDetailsService() {
return userConnector;
}
}
另一个过滤器:
public class MyTokenAuthorizationFilter extends OncePerRequestFilter {
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
private TokenEncoder tokenEncoder;
private RememberMeServices rememberMeServices = new NullRememberMeServices();
public MyTokenAuthorizationFilter(TokenEncoder tokenEncoder) {
super();
this.tokenEncoder = tokenEncoder;
}
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if(request.getHeader("X-API-TOKEN") == null) {
filterChain.doFilter(request, response);
} else {
String uid = tokenEncoder.isValid(request.getHeader("X-API-TOKEN"));
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(uid, "");
token.setDetails(authenticationDetailsSource.buildDetails(request));
Authentication authResult = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(token);
rememberMeServices.loginSuccess(request, response, authResult);
}
filterChain.doFilter(request, response);
}
@Override
public void afterPropertiesSet() {
Assert.notNull(authenticationManager,
"An AuthenticationManager is required");
Assert.notNull(this.authenticationEntryPoint,
"An AuthenticationEntryPoint is required");
}
}
我很满意这两个过滤器都在工作,但问题是它们没有被链接。似乎该请求在两个过滤器上传播了两次,并且根据spring-security文档,我的json回答加倍了,这是正常的。 如何根据我在标头中找到的内容执行每个过滤器,如果其中一个成功,请跳过第二个步骤?