Swagger UI将身份验证令牌传递给标头中的API调用

kr98yfug  于 2023-05-28  发布在  其他
关注(0)|答案(8)|浏览(243)

我是斯威格的新手
我正在使用Swagger UI生成Swagger文档。我有两个API调用。第一个调用是根据用户名和密码生成令牌。第二次调用需要第一次调用生成的令牌。
如何使用Swagger UI设置第二次调用的令牌?

ars1skjm

ars1skjm1#

@ApiImplicitParams@ApiImplicitParam应该可以做到这一点:

@GET
@Produces("application/json")
@ApiImplicitParams({
    @ApiImplicitParam(name = "Authorization", value = "Authorization token", 
                      required = true, dataType = "string", paramType = "header") })
public String getUser(@PathParam("username") String userName) {
    ...
}

来自文档:
您可能希望手动描述操作参数。这可能是由于各种原因,例如:

  • 使用不使用JAX-RS注解的Servlet。
  • 想要隐藏定义的参数,并使用完全不同的定义覆盖它。
  • 描述在到达JAX-RS实现之前由过滤器或其他资源使用的参数。

Swagger UI将更新,以便您可以从那里发送令牌。不需要更改HTML。

    • 注意:**不久前,在使用Swagger编写REST API文档时,我意识到仅仅添加@ApiImplicitParam是不够的(即使只有一个参数)。另外,您还需要添加@ApiImplicitParams
o75abkj4

o75abkj42#

我配置2.9.2 Swagger版本在Swagger界面添加Authorization并发送Bearer token

@Configuration
    public class SwaggerConfiguration{

        //...

          @Bean
          public Docket api(ServletContext servletContext) {
            return new Docket(DocumentationType.SWAGGER_2)...
                .securitySchemes(Arrays.asList(apiKey()))
                .securityContexts(Collections.singletonList(securityContext()));
          }

          private SecurityContext securityContext() {
            return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.regex("/.*")).build();
          }

          private List<SecurityReference> defaultAuth() {
            final AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
            final AuthorizationScope[] authorizationScopes = new AuthorizationScope[]{authorizationScope};
            return Collections.singletonList(new SecurityReference("Bearer", authorizationScopes));
          }

          private ApiKey apiKey() {
            return new ApiKey("Bearer", "Authorization", "header");
          }
    }
t98cgbkg

t98cgbkg3#

另一个选项是添加globalOperationParameters。它将在每个端点中添加一个用于授权的字段。
定义授权标头参数:

Parameter authHeader = new ParameterBuilder()
  .parameterType("header")
  .name("Authorization")
  .modelRef(new ModelRef("string"))
  .build();

将其添加到Docket配置中:

return new Docket(DocumentationType.SWAGGER_2)
    .select()
    .apis(...)
    .paths(...)
    .build()
    .apiInfo(...)
    .globalOperationParameters(Collections.singletonList(authHeader));

它看起来像这样:

vc9ivgsu

vc9ivgsu4#

有一种方法可以使用responseInterceptor和requestInterceptor
首先使用responseInterceptor捕获第一个API调用的响应并保存令牌(在本例中保存在本地存储中),然后使用requestInterceptorAuthorization标头与保存的令牌一起添加。

const ui = SwaggerUIBundle({
               ...
                responseInterceptor:
                    function (response) {
                        if (response.obj.access_token) {
                            console.log(response.obj.access_token)
                            const token = response.obj.access_token;
                            localStorage.setItem("token", token)
                        }

                        return response;
                    },
                requestInterceptor:
                    function (request) {
                        console.log('[Swagger] intercept try-it-out request');
                        request.headers.Authorization = "Bearer " + localStorage.getItem("token");
                        return request;
                }
           }
kognpnkq

kognpnkq5#

我相信你必须定制swagger index page来实现这一点。
您可以隐藏输入'input_apiKey',并添加两个用户名和密码输入。然后,您进行一个 AJAX 调用,用您的令牌更新隐藏的输入。

qnyhuwrf

qnyhuwrf6#

这是一个老问题,但这是我最近在2.7.0版本中为我的JWT令牌解决它的方法
在swagger配置中,添加SecurityConfiguration bean。重要部分是保留第五个参数为空或空。

@Bean
    public SecurityConfiguration securityInfo() {
        return new SecurityConfiguration(null, null, null, null, "", ApiKeyVehicle.HEADER,"Authorization","");
    }

securitySchemes(Lists.newArrayList(apiKey()))添加到主Docket bean中。

@Bean
    public Docket docket()
    {
        return new Docket(DocumentationType.SWAGGER_2).select()
            .....build().apiInfo(...).securitySchemes(Lists.newArrayList(apiKey()));
    }

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

然后在UI中,需要点击Authorize按钮,输入“Bearer access_token”(用于Authorization文本框),其中access_token是jWT token服务器提供的令牌。
保存此授权后,将对所有端点生效。为每个端点添加单独的文本字段看起来非常麻烦。

uajslkp6

uajslkp67#

使用带有springdoc-openapi-maven-plugin的SpringDoc,我的选择是使用SwaggerConfig.Java:

@Configuration
public class SwaggerConfiguration  {
    @Bean
    public OpenAPI customOpenAPI(@Value("${project.version}") String appVersion) {
        OpenAPI openApi = new OpenAPI();
                openApi.info(
                    new Info()
                .title("Title Example")
                .version(appVersion)
                .description("Swagger server created using springdocs - a library for OpenAPI 3 with spring boot.")
                );

                openApi.components(
                        new Components().addSecuritySchemes("bearer-jwt",
                new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
                        .in(SecurityScheme.In.HEADER).name("Authorization"))
                );

                openApi.addSecurityItem(
                        new SecurityRequirement().addList("bearer-jwt", Arrays.asList("read", "write"))
                );

        return openApi;
    }
}
lnxxn5zx

lnxxn5zx8#

使用Swagger UI 4,我通过配置persistAuthorizationrequestInterceptor Swagger UI配置参数完成了这一点:
1.将persistAuthorization设置为true使其将授权数据存储在浏览器的localStorage
1.添加一个requestInterceptor JS函数,修改请求以沿着accept_token
下面是我的requestInterceptor函数:

function(request) {
    let authorize_json = window.sessionStorage.getItem('authorized')
    if (!authorize_json || authorize_json === '{}') {
        authorize_json = window.localStorage.getItem('authorized')
        if (!authorize_json) {
            return request
        }
    }

    // move from localStorage to sessionStorage, for better security
    window.localStorage.removeItem('authorized')
    window.sessionStorage.setItem('authorized', authorize_json)

    const persistedAuthData = JSON.parse(authorize_json)
    if (!persistedAuthData.oauth2) {
        return request
    }
    const access_token = persistedAuthData.oauth2.token.access_token
    request.headers['Authorization'] = 'Bearer ' + access_token
    return request
}

相关问题