亲爱的
我正在使用 Spring Fox 和 Spring Security。我有一个自定义 JwrRequestFilter,它从请求中提取 jwt 并对用户进行身份验证。
我的问题是,当用户点击 /swagger-ui.html 时,我需要出现一个基本的弹出身份验证警报
这是我的安全配置.configure()方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.exceptionHandling()
.authenticationEntryPoint(new JwtAuthenticationEntryPoint())
.and()
.authorizeRequests()
.antMatchers("/",
"/error",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/review/notify",
"/demo/**",
"/communication/**",
"/info/**",
"/images/***",
"/images/**/**",
"/webjars/**",
"/scrapper/**",
"/", "/actuator/**").permitAll()
.antMatchers("/auth/**",
"/oauth2/**", "/internal/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.authorizationEndpoint()
.baseUri("/oauth2/authorize")
.authorizationRequestRepository(cookieAuthorizationRequestRepository())
.and()
.redirectionEndpoint()
.baseUri("/oauth2/callback/*")
.and()
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(oAuth2AuthenticationFailureHandler);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
还有 jwtRequestFilter:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader(Constants.AUTHORIZATION_HEADER);
String username = null;
String jwtToken = null;
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null && requestTokenHeader.startsWith(Constants.TOKEN_PREFIX)) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getEmailFromToken(jwtToken);
} catch (IllegalArgumentException e) {
log.warn("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
log.warn("JWT Token has expired");
}
} else {
log.warn("JWT Token does not begin with Bearer String");
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (username.equals("scrapper-api")) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
"scrapper-api", null, Arrays.asList());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
} else {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
// if token is valid configure Spring Security to manually set
// authentication
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
}
chain.doFilter(request, response);
}
Spring Fox版本为3.0 Spring框架版本是2.7.0
必须实现第二个 WebSecurityConfigurerAdapter
@Configuration
@Order(1)
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {
@Autowired
PasswordEncoder encoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/swagger-ui/**")
.authorizeRequests()
.anyRequest().hasRole("FORM_USER")
.and()
.httpBasic();
}
// If you want to use in-memory authentication for testing
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password(encoder.encode("test"))
.roles("FORM_USER");
}
}
这是使用基本的内存中身份验证,这对于我的情况来说已经足够了,但可以扩展以使用 UserDetailsService