使用 JWT 身份验证时如何通过基本身份验证保护 swagger UI

问题描述 投票:0回答:1

亲爱的

我正在使用 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

spring spring-security swagger-ui springfox
1个回答
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

更多参考:如何在 Spring Boot 中使用 JWT 身份验证实现基本身份验证?

© www.soinside.com 2019 - 2024. All rights reserved.