Java WebSecurity配置antMatcher()不忽略集成测试中外部API的特定url
我正在Spring Boot应用程序中实现AWS Cognito安全机制。启用安全性后,我遇到了一个针对外部API的现有集成测试问题。 作为测试结果,我收到一个错误: 2020-11-15 18:18:20.033错误12072---[main] .c.s.f.AwsCognitoJwtAuthenticationFilter:操作无效,没有令牌 找到MockHttpServletResponse: 状态=401 错误消息=null Headers=[访问控制允许来源:“*”,访问控制允许方法:“POST、GET、OPTIONS、PUT、DELETE”, 访问控制最大年龄:“3600”, 访问控制允许凭据:“true”, 访问控制允许标题:“内容类型,授权”, 内容类型:“应用程序/json”] 内容类型=应用程序/json Body={“data”:null,“exception”:{“message”:“JWT Handle exception”,“httpStatusCode”:“INTERNAL_SERVER_ERROR”,“detail”:null} 我的Java WebSecurity配置antMatcher()不忽略集成测试中外部API的特定url,java,spring,spring-security,amazon-cognito,spring-security-oauth2,Java,Spring,Spring Security,Amazon Cognito,Spring Security Oauth2,我正在Spring Boot应用程序中实现AWS Cognito安全机制。启用安全性后,我遇到了一个针对外部API的现有集成测试问题。 作为测试结果,我收到一个错误: 2020-11-15 18:18:20.033错误12072---[main] .c.s.f.AwsCognitoJwtAuthenticationFilter:操作无效,没有令牌 找到MockHttpServletResponse: 状态=401 错误消息=null Headers=[访问控制允许来源:“*”,访问控制允许方法:
WebSecurityConfiguration
如下所示:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableTransactionManagement
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private CustomAuthenticationProvider authProvider;
private AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter;
private AccountControllerExceptionHandler exceptionHandler;
private static final String LOGIN_URL = "/auth/login";
private static final String LOGOUT_URL = "/auth/signOut";
@Autowired
public WebSecurityConfiguration(
CustomAuthenticationProvider authProvider,
AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter,
AccountControllerExceptionHandler exceptionHandler) {
this.authProvider = authProvider;
this.awsCognitoJwtAuthenticationFilter = awsCognitoJwtAuthenticationFilter;
this.exceptionHandler = exceptionHandler;
}
public WebSecurityConfiguration() {
super(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider).eraseCredentials(false);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(WebSecurity web) {
// TokenAuthenticationFilter will ignore the below paths
web.ignoring().antMatchers("/auth");
web.ignoring().antMatchers("/auth/**");
web.ignoring().antMatchers("/v2/api-docs");
web.ignoring().antMatchers(GET, "/nutrition/api/**");
web.ignoring().antMatchers(GET, "/**");
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.addFilterAfter(corsFilter(), ExceptionTranslationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
.accessDeniedHandler(new RestAccessDeniedHandler())
.and()
.anonymous()
.and()
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth")
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(
awsCognitoJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.formLogin(formLogin -> formLogin.loginProcessingUrl(LOGIN_URL).failureHandler(exceptionHandler))
.logout(logout -> logout.permitAll().logoutUrl(LOGOUT_URL))
.csrf(AbstractHttpConfigurer::disable);
}
private CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader(ORIGIN);
config.addAllowedHeader(CONTENT_TYPE);
config.addAllowedHeader(ACCEPT);
config.addAllowedHeader(AUTHORIZATION);
config.addAllowedMethod(GET);
config.addAllowedMethod(PUT);
config.addAllowedMethod(POST);
config.addAllowedMethod(OPTIONS);
config.addAllowedMethod(DELETE);
config.addAllowedMethod(PATCH);
config.setMaxAge(3600L);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/**", config);
return new CorsFilter();
}
}
@RestController
@RequestMapping("/nutrition/api/")
class NutritionixApiController {
private ProductFacadeImpl productFacadeImpl;
public NutritionixApiController(
ProductFacadeImpl productFacadeImpl) {
this.productFacadeImpl = productFacadeImpl;
}
@GetMapping("/productDetails")
public ResponseEntity<Set<RecipeIngredient>> productsDetails(@RequestParam String query) {
//logic here
}
}
@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final CognitoAuthenticationService cognitoService;
@SuppressWarnings("unchecked")
@Override
public Authentication authenticate(Authentication authentication) {
AuthenticationRequest authenticationRequest;
if (authentication != null) {
authenticationRequest = new AuthenticationRequest();
Map<String, String> credentials = (Map<String, String>) authentication.getCredentials();
authenticationRequest.setNewPassword(credentials.get(NEW_PASS_WORD_KEY));
authenticationRequest.setPassword(credentials.get(PASS_WORD_KEY));
authenticationRequest.setUsername(authentication.getName());
SpringSecurityUser userAuthenticated = cognitoService.authenticate(authenticationRequest);
if (userAuthenticated != null) {
Map<String, String> authenticatedCredentials = new HashMap<>();
authenticatedCredentials.put(ACCESS_TOKEN_KEY, userAuthenticated.getAccessToken());
authenticatedCredentials.put(EXPIRES_IN_KEY, userAuthenticated.getExpiresIn().toString());
authenticatedCredentials.put(ID_TOKEN_KEY, userAuthenticated.getIdToken());
authenticatedCredentials.put(PASS_WORD_KEY, userAuthenticated.getPassword());
authenticatedCredentials.put(REFRESH_TOKEN_KEY, userAuthenticated.getRefreshToken());
authenticatedCredentials.put(TOKEN_TYPE_KEY, userAuthenticated.getTokenType());
return new UsernamePasswordAuthenticationToken(
userAuthenticated.getUsername(),
authenticatedCredentials,
userAuthenticated.getAuthorities());
} else {
return null;
}
} else {
throw new UsernameNotFoundException("No application user for given username");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
AwsCognitoJwtAuthenticationFilter
@Slf4j
public class AwsCognitoJwtAuthenticationFilter extends OncePerRequestFilter {
private static final String ERROR_OCCURRED_WHILE_PROCESSING_THE_TOKEN =
"Error occured while processing the token";
private static final String INVALID_TOKEN_MESSAGE = "Invalid Token";
private final AwsCognitoIdTokenProcessor awsCognitoIdTokenProcessor;
@Autowired private ApplicationContext appContext;
public AwsCognitoJwtAuthenticationFilter(AwsCognitoIdTokenProcessor awsCognitoIdTokenProcessor) {
this.awsCognitoIdTokenProcessor = awsCognitoIdTokenProcessor;
}
private void createExceptionResponse(
ServletRequest request, ServletResponse response, CognitoException exception)
throws IOException {
HttpServletRequest req = (HttpServletRequest) request;
ExceptionController exceptionController;
ObjectMapper objMapper = new ObjectMapper();
exceptionController = appContext.getBean(ExceptionController.class);
ResponseData<Object> responseData = exceptionController.handleJwtException(req, exception);
HttpServletResponse httpResponse = CorsHelper.addResponseHeaders(response);
final HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(httpResponse);
wrapper.setStatus(HttpStatus.UNAUTHORIZED.value());
wrapper.setContentType(APPLICATION_JSON_VALUE);
wrapper.getWriter().println(objMapper.writeValueAsString(responseData));
wrapper.getWriter().flush();
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
Authentication authentication;
try {
authentication = awsCognitoIdTokenProcessor.getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (BadJOSEException e) {
SecurityContextHolder.clearContext();
log.error(e.getMessage());
createExceptionResponse(
request,
response,
new CognitoException(
INVALID_TOKEN_MESSAGE,
CognitoException.INVALID_TOKEN_EXCEPTION_CODE,
e.getMessage()));
return;
} catch (CognitoException e) {
SecurityContextHolder.clearContext();
log.error(e.getMessage());
createExceptionResponse(
request,
response,
new CognitoException(
e.getErrorMessage(),
CognitoException.INVALID_TOKEN_EXCEPTION_CODE,
e.getDetailErrorMessage()));
return;
} catch (Exception e) {
SecurityContextHolder.clearContext();
log.error(e.getMessage());
createExceptionResponse(
request,
response,
new CognitoException(
ERROR_OCCURRED_WHILE_PROCESSING_THE_TOKEN,
CognitoException.INVALID_TOKEN_EXCEPTION_CODE,
e.getMessage()));
return;
}
filterChain.doFilter(request, response);
}
}
CognitoJWT自动配置
@Configuration
@Import(AWSConfig.class)
@ConditionalOnClass({AwsCognitoJwtAuthenticationFilter.class, AwsCognitoIdTokenProcessor.class})
public class CognitoJwtAutoConfiguration {
private final AWSConfig jwtConfiguration;
public CognitoJwtAutoConfiguration(AWSConfig jwtConfiguration) {
this.jwtConfiguration = jwtConfiguration;
}
@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public CognitoJwtIdTokenCredentialsHolder awsCognitoCredentialsHolder() {
return new CognitoJwtIdTokenCredentialsHolder();
}
@Bean
public AwsCognitoIdTokenProcessor awsCognitoIdTokenProcessor() {
return new AwsCognitoIdTokenProcessor();
}
@Bean
public CognitoJwtAuthenticationProvider jwtAuthenticationProvider() {
return new CognitoJwtAuthenticationProvider();
}
@Bean
public AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter() {
return new AwsCognitoJwtAuthenticationFilter(awsCognitoIdTokenProcessor());
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
public ConfigurableJWTProcessor configurableJWTProcessor() throws MalformedURLException {
ResourceRetriever resourceRetriever =
new DefaultResourceRetriever(CONNECTION_TIMEOUT, READ_TIMEOUT);
// https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json.
URL jwkSetURL = new URL(jwtConfiguration.getJwkUrl());
// Creates the JSON Web Key (JWK)
JWKSource keySource = new RemoteJWKSet(jwkSetURL, resourceRetriever);
ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();
JWSKeySelector keySelector = new JWSVerificationKeySelector(RS256, keySource);
jwtProcessor.setJWSKeySelector(keySelector);
return jwtProcessor;
}
@Bean
public AWSCognitoIdentityProvider awsCognitoIdentityProvider() {
return AWSCognitoIdentityProviderClientBuilder.standard()
.withRegion(Regions.EU_CENTRAL_1)
.withCredentials(getCredentialsProvider())
.build();
}
@Bean
public AWSCredentialsProvider getCredentialsProvider() {
return new ClasspathPropertiesFileCredentialsProvider();
}
}
我想将我的控制器URL排除在需要授权的端点之外
基于视觉测试的控制器看起来像:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableTransactionManagement
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private CustomAuthenticationProvider authProvider;
private AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter;
private AccountControllerExceptionHandler exceptionHandler;
private static final String LOGIN_URL = "/auth/login";
private static final String LOGOUT_URL = "/auth/signOut";
@Autowired
public WebSecurityConfiguration(
CustomAuthenticationProvider authProvider,
AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter,
AccountControllerExceptionHandler exceptionHandler) {
this.authProvider = authProvider;
this.awsCognitoJwtAuthenticationFilter = awsCognitoJwtAuthenticationFilter;
this.exceptionHandler = exceptionHandler;
}
public WebSecurityConfiguration() {
super(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider).eraseCredentials(false);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(WebSecurity web) {
// TokenAuthenticationFilter will ignore the below paths
web.ignoring().antMatchers("/auth");
web.ignoring().antMatchers("/auth/**");
web.ignoring().antMatchers("/v2/api-docs");
web.ignoring().antMatchers(GET, "/nutrition/api/**");
web.ignoring().antMatchers(GET, "/**");
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.addFilterAfter(corsFilter(), ExceptionTranslationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
.accessDeniedHandler(new RestAccessDeniedHandler())
.and()
.anonymous()
.and()
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth")
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(
awsCognitoJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.formLogin(formLogin -> formLogin.loginProcessingUrl(LOGIN_URL).failureHandler(exceptionHandler))
.logout(logout -> logout.permitAll().logoutUrl(LOGOUT_URL))
.csrf(AbstractHttpConfigurer::disable);
}
private CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader(ORIGIN);
config.addAllowedHeader(CONTENT_TYPE);
config.addAllowedHeader(ACCEPT);
config.addAllowedHeader(AUTHORIZATION);
config.addAllowedMethod(GET);
config.addAllowedMethod(PUT);
config.addAllowedMethod(POST);
config.addAllowedMethod(OPTIONS);
config.addAllowedMethod(DELETE);
config.addAllowedMethod(PATCH);
config.setMaxAge(3600L);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/**", config);
return new CorsFilter();
}
}
@RestController
@RequestMapping("/nutrition/api/")
class NutritionixApiController {
private ProductFacadeImpl productFacadeImpl;
public NutritionixApiController(
ProductFacadeImpl productFacadeImpl) {
this.productFacadeImpl = productFacadeImpl;
}
@GetMapping("/productDetails")
public ResponseEntity<Set<RecipeIngredient>> productsDetails(@RequestParam String query) {
//logic here
}
}
@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final CognitoAuthenticationService cognitoService;
@SuppressWarnings("unchecked")
@Override
public Authentication authenticate(Authentication authentication) {
AuthenticationRequest authenticationRequest;
if (authentication != null) {
authenticationRequest = new AuthenticationRequest();
Map<String, String> credentials = (Map<String, String>) authentication.getCredentials();
authenticationRequest.setNewPassword(credentials.get(NEW_PASS_WORD_KEY));
authenticationRequest.setPassword(credentials.get(PASS_WORD_KEY));
authenticationRequest.setUsername(authentication.getName());
SpringSecurityUser userAuthenticated = cognitoService.authenticate(authenticationRequest);
if (userAuthenticated != null) {
Map<String, String> authenticatedCredentials = new HashMap<>();
authenticatedCredentials.put(ACCESS_TOKEN_KEY, userAuthenticated.getAccessToken());
authenticatedCredentials.put(EXPIRES_IN_KEY, userAuthenticated.getExpiresIn().toString());
authenticatedCredentials.put(ID_TOKEN_KEY, userAuthenticated.getIdToken());
authenticatedCredentials.put(PASS_WORD_KEY, userAuthenticated.getPassword());
authenticatedCredentials.put(REFRESH_TOKEN_KEY, userAuthenticated.getRefreshToken());
authenticatedCredentials.put(TOKEN_TYPE_KEY, userAuthenticated.getTokenType());
return new UsernamePasswordAuthenticationToken(
userAuthenticated.getUsername(),
authenticatedCredentials,
userAuthenticated.getAuthorities());
} else {
return null;
}
} else {
throw new UsernameNotFoundException("No application user for given username");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
或
但没有理想的效果。我有点困惑为什么忽略.antMatchers()
不起作用,因此我将非常感谢您就如何解决上述问题提出的建议
编辑
我回到话题上来,但结果是一样的。在WebSecurityConfiguration
中,我注释掉了@EnableGlobalMethodSecurity(preprestenabled=true)
以尝试配置,但没有preprestenabled=true
,但没有理想的效果。端点/auth
也有同样的问题,在配置中被忽略。
我仿效了教程,教程在这里有效
但是我对我的代码进行了一些重构,以摆脱带有@Autowired
的字段注入,但没有进行彻底的更改和隐藏的逻辑
此外,classCustomAuthenticationProvider
看起来像:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableTransactionManagement
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private CustomAuthenticationProvider authProvider;
private AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter;
private AccountControllerExceptionHandler exceptionHandler;
private static final String LOGIN_URL = "/auth/login";
private static final String LOGOUT_URL = "/auth/signOut";
@Autowired
public WebSecurityConfiguration(
CustomAuthenticationProvider authProvider,
AwsCognitoJwtAuthenticationFilter awsCognitoJwtAuthenticationFilter,
AccountControllerExceptionHandler exceptionHandler) {
this.authProvider = authProvider;
this.awsCognitoJwtAuthenticationFilter = awsCognitoJwtAuthenticationFilter;
this.exceptionHandler = exceptionHandler;
}
public WebSecurityConfiguration() {
super(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider).eraseCredentials(false);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(WebSecurity web) {
// TokenAuthenticationFilter will ignore the below paths
web.ignoring().antMatchers("/auth");
web.ignoring().antMatchers("/auth/**");
web.ignoring().antMatchers("/v2/api-docs");
web.ignoring().antMatchers(GET, "/nutrition/api/**");
web.ignoring().antMatchers(GET, "/**");
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.addFilterAfter(corsFilter(), ExceptionTranslationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
.accessDeniedHandler(new RestAccessDeniedHandler())
.and()
.anonymous()
.and()
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth")
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(
awsCognitoJwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.formLogin(formLogin -> formLogin.loginProcessingUrl(LOGIN_URL).failureHandler(exceptionHandler))
.logout(logout -> logout.permitAll().logoutUrl(LOGOUT_URL))
.csrf(AbstractHttpConfigurer::disable);
}
private CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader(ORIGIN);
config.addAllowedHeader(CONTENT_TYPE);
config.addAllowedHeader(ACCEPT);
config.addAllowedHeader(AUTHORIZATION);
config.addAllowedMethod(GET);
config.addAllowedMethod(PUT);
config.addAllowedMethod(POST);
config.addAllowedMethod(OPTIONS);
config.addAllowedMethod(DELETE);
config.addAllowedMethod(PATCH);
config.setMaxAge(3600L);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/**", config);
return new CorsFilter();
}
}
@RestController
@RequestMapping("/nutrition/api/")
class NutritionixApiController {
private ProductFacadeImpl productFacadeImpl;
public NutritionixApiController(
ProductFacadeImpl productFacadeImpl) {
this.productFacadeImpl = productFacadeImpl;
}
@GetMapping("/productDetails")
public ResponseEntity<Set<RecipeIngredient>> productsDetails(@RequestParam String query) {
//logic here
}
}
@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final CognitoAuthenticationService cognitoService;
@SuppressWarnings("unchecked")
@Override
public Authentication authenticate(Authentication authentication) {
AuthenticationRequest authenticationRequest;
if (authentication != null) {
authenticationRequest = new AuthenticationRequest();
Map<String, String> credentials = (Map<String, String>) authentication.getCredentials();
authenticationRequest.setNewPassword(credentials.get(NEW_PASS_WORD_KEY));
authenticationRequest.setPassword(credentials.get(PASS_WORD_KEY));
authenticationRequest.setUsername(authentication.getName());
SpringSecurityUser userAuthenticated = cognitoService.authenticate(authenticationRequest);
if (userAuthenticated != null) {
Map<String, String> authenticatedCredentials = new HashMap<>();
authenticatedCredentials.put(ACCESS_TOKEN_KEY, userAuthenticated.getAccessToken());
authenticatedCredentials.put(EXPIRES_IN_KEY, userAuthenticated.getExpiresIn().toString());
authenticatedCredentials.put(ID_TOKEN_KEY, userAuthenticated.getIdToken());
authenticatedCredentials.put(PASS_WORD_KEY, userAuthenticated.getPassword());
authenticatedCredentials.put(REFRESH_TOKEN_KEY, userAuthenticated.getRefreshToken());
authenticatedCredentials.put(TOKEN_TYPE_KEY, userAuthenticated.getTokenType());
return new UsernamePasswordAuthenticationToken(
userAuthenticated.getUsername(),
authenticatedCredentials,
userAuthenticated.getAuthorities());
} else {
return null;
}
} else {
throw new UsernameNotFoundException("No application user for given username");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
@组件
@所需参数构造函数
公共类CustomAuthenticationProvider实现AuthenticationProvider{
私有最终CognitoAuthenticationService cognitoService;
@抑制警告(“未选中”)
@凌驾
公共身份验证(身份验证){
AuthenticationRequest AuthenticationRequest;
if(身份验证!=null){
authenticationRequest=新的authenticationRequest();
映射凭据=(映射)身份验证。getCredentials();
authenticationRequest.setNewPassword(credentials.get(NEW\u PASS\u WORD\u KEY));
authenticationRequest.setPassword(credentials.get(PASS_WORD_KEY));
authenticationRequest.setUsername(authentication.getName());
SpringSecurityUser userAuthenticated=cognitoService.authenticate(authenticationRequest);
if(userAuthenticated!=null){
Map authenticatedCredentials=new HashMap();
authenticatedCredentials.put(访问令牌密钥,userAuthenticated.getAccessToken());
authenticatedCredentials.put(EXPIRES_IN_KEY,userAuthenticated.getExpiresIn().toString());
authenticatedCredentials.put(ID_TOKEN_KEY,userAuthenticated.getIdToken());
authenticatedCredentials.put(传递单词密钥,userAuthenticated.getPassword());
authenticatedCredentials.put(刷新令牌密钥,userAuthenticated.getRefreshToken());
authenticatedCredentials.put(令牌类型密钥,userAuthenticated.getTokenType());
返回新的用户名PasswordAuthenticationToken(
userAuthenticated.getUsername(),
认证凭证,
userAuthenticated.getAuthorities());
}否则{
返回null;
}
}否则{
抛出新的UsernameNotFoundException(“给定用户名没有应用程序用户”);
}
}
@凌驾
公共布尔支持(类身份验证){
返回authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
老实说,我不知道还有什么可以做得更多,以解决这个问题与不工作的过滤器。将非常感谢您的帮助。尽管您指出了正确的忽略模式,而且Spring Security实际上忽略了过滤器,我认为它仍然在执行,因为Spring可能再次在安全链之外注册了过滤器,因为您在
CognitoJwtAutoConfiguration
中使用@Bean
公开了过滤器
为了避免这个问题,请在代码中执行以下修改(基本上,确保只有一个过滤器实例)。首先,在WebSecurityConfiguration
中:
@配置
@启用Web安全性
@EnableGlobalMethodSecurity(Prespenabled=true)
@启用事务管理
公共类WebSecurity配置扩展了WebSecurity配置适配器{
私有CustomAuthenticationProvider authProvider;
private AccountControllerExceptionHandler exceptionHandler;
私有静态最终字符串LOGIN_URL=“/auth/LOGIN”;
私有静态最终字符串LOGOUT_URL=“/auth/signOut”;
@自动连线
公共网站安全配置(
CustomAuthenticationProvider authProvider,
AccountControllerExceptionHandler(异常处理程序){
//不再将AwsCognitoJwtAuthenticationFilter()作为实例文件提供
this.authProvider=authProvider;
this.exceptionHandler=exceptionHandler;
}
公共网站安全配置(){
超级(真);
}
@凌驾
受保护的无效配置(AuthenticationManagerBuilder身份验证){
auth.authenticationProvider(authProvider).擦除凭据(false);
}
@豆子
@凌驾
公共AuthenticationManager authenticationManagerBean()引发异常{
返回super.authenticationManagerBean();
}
@凌驾
公共void配置(WebSecurity web){
//TokenAuthenticationFilter将忽略以下路径