如何在 Swagger-ui 中显示 Spring Security 用户名密码身份验证过滤器 url?

Posted

技术标签:

【中文标题】如何在 Swagger-ui 中显示 Spring Security 用户名密码身份验证过滤器 url?【英文标题】:How to show Spring Security Username Password Authentication Filter url in Swagger-ui? 【发布时间】:2021-03-18 07:09:14 【问题描述】:

我正在使用 Spring Security 并使用用户名密码身份验证过滤器。我想知道是否可以在 Swagger 中显示身份验证端点。这个端点是由过滤器自动生成的(据我所知)。

我很想让这个端点出现在 Swagger-ui 中,否则我需要在 Postman 中登录,然后将 Swagger 与 Jwt Token 一起使用,这有点奇怪。

这是 UsernamePasswordAuthenticationFilter:

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter 
private final AuthenticationManager authenticationManager;

public AuthenticationFilter(AuthenticationManager authenticationManager) 
    this.authenticationManager = authenticationManager;


@Override
public Authentication attemptAuthentication(HttpServletRequest req,
                                            HttpServletResponse res) 
    try 
        LoginDTO userEntity = new ObjectMapper().readValue(req.getInputStream(), LoginDTO.class);

        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(userEntity.getEmail(),
                        userEntity.getPassword(), new ArrayList<>())
        );
     catch (IOException e) 
        throw new RuntimeException(e);
    


@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
                                        Authentication auth) throws IOException 
    Token token = new Token(JwtUtils.createAccessToken(ZonedDateTime.now().plusMinutes(10), TenantContext.getCurrentUserUniqueIdentifier(), TenantContext.getCurrentTenantId()),
            JwtUtils.createRefreshToken(ZonedDateTime.now().plusMonths(3)));
    PrintWriter out = res.getWriter();
    res.setContentType("application/json");
    res.setCharacterEncoding("UTF-8");
    out.print(new ObjectMapper().writeValueAsString(token));
    out.flush();

这是我从 WebSecurityAdapter 扩展而来的类。如您所见,我将 url 设置为 /v1/login。

@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 
    private final UserEntityDetailsService userEntityDetailsService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(HttpMethod.POST, "/v1/account").permitAll()
                .antMatchers(HttpMethod.GET, "/v1/healthcheck").permitAll()
                .antMatchers("/v1/recoverpassword/**").permitAll()
                .antMatchers("/swagger-ui/**", "/v2/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/**", "/swagger-ui.html", "/webjars/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(getAuthenticationFilter())
                .addFilter(new AuthorizationFilter(authenticationManager()))
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    

    @Bean
    CorsConfigurationSource corsConfigurationSource() 
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
        return source;
    

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userEntityDetailsService).passwordEncoder(bCryptPasswordEncoder);
    

    public AuthenticationFilter getAuthenticationFilter() throws Exception 
        final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager());
        filter.setFilterProcessesUrl("/v1/login");
        return filter;
    

这是我的 SpringFox 配置:

@Configuration
@EnableSwagger2
public class SpringFoxConfig 

    private ApiInfo apiInfo() 
        return new ApiInfoBuilder()
                .title("Projeto List")
                .description("All endpoints of Projeto List Api")
                .build();
    

    @Bean
    public Docket api() 
        return new Docket(DocumentationType.SWAGGER_2)
                .useDefaultResponseMessages(false)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("br.com.projetolist.resource"))
                .paths(PathSelectors.ant("/**"))
                .build()
                .securitySchemes(Arrays.asList(apiKey()));
    

    /**
     * SwaggerUI information
     */
    @Bean
    UiConfiguration uiConfig() 
        return UiConfigurationBuilder.builder()
                .deepLinking(true)
                .displayOperationId(false)
                .defaultModelsExpandDepth(1)
                .defaultModelExpandDepth(1)
                .defaultModelRendering(ModelRendering.MODEL)
                .displayRequestDuration(false)
                .docExpansion(DocExpansion.NONE)
                .filter(false)
                .maxDisplayedTags(null)
                .operationsSorter(OperationsSorter.ALPHA)
                .showExtensions(false)
                .tagsSorter(TagsSorter.ALPHA)
                .validatorUrl(null)
                .build();
    

    private ApiKey apiKey() 
        return new ApiKey("jwtToken", "Authorization", "header");
    


【问题讨论】:

【参考方案1】:

您可以向其中一个控制器添加类似的方法。在您的情况下,它将是 URL 为“/v1/login”的 POST 方法。

@PostMapping("/v1/login")
@ResponseStatus(OK)
fun login(@RequestBody userCreds: UserCredentials) 

【讨论】:

以上是关于如何在 Swagger-ui 中显示 Spring Security 用户名密码身份验证过滤器 url?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Swagger + 自定义 swagger-ui.html

无法从 spring-boot 应用程序中调出 swagger-ui

spring boot2集成api文档工具swagger-ui(下)

swagger-ui 和 spring webflux 出现 404 错误

spring boot2集成api文档工具swagger-ui(上)

spring boot整合swagger时,打开swagger-ui中文出现乱码