OpenAPI3基于Spring Boot通过基本身份验证显示方法

huangapple go评论115阅读模式
英文:

OpenAPI3 show methods based on Basic Authentication via Spring Boot

问题

我将以下内容添加到我的Spring Boot应用程序的依赖中:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.4.3</version>
    <type>pom.sha512</type>
</dependency>

然后,我可以打开以下链接:
https://localhost:8443/v3/api-docs

浏览器会要求我输入凭据,只要我输入正确的用户名和密码,它就能正常工作,但它会显示所有全局可用的方法。我希望只有用户有权限的方法才会显示在API文档中。

对于特定的方法,我使用以下标签来授权我的调用:
`@PreAuthorize("hasRole('USER') OR hasRole('ADMIN')")`

这是我的Web安全配置类:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("user").password(new BCryptPasswordEncoder().encode("blabl")).roles("USER")
                .and()
                .withUser("admin").password(new BCryptPasswordEncoder().encode("blabla")).roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}
英文:

I added this dependency to my Spring Boot application

 &lt;dependency&gt;
	  &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
	  &lt;artifactId&gt;springdoc-openapi-ui&lt;/artifactId&gt;
	  &lt;version&gt;1.4.3&lt;/version&gt;
	  &lt;type&gt;pom.sha512&lt;/type&gt;
	 &lt;/dependency&gt;

I then was able to open :
https://localhost:8443/v3/api-docs

The browser does ask me for my credentials, and as long as I enter the user/password right it works, but it shows me ALL the methods that are available globally. I would like only the methods the user has rights to, to show up in the api docs.

For a specific method is use this tag to authorize my call:
@PreAuthorize(&quot;hasRole(&#39;USER&#39;) OR hasRole(&#39;ADMIN&#39;)&quot;)

This is my web security config class:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser(&quot;user&quot;).password(new BCryptPasswordEncoder().encode(&quot;blabl&quot;)).roles(&quot;USER&quot;)
                .and()
                .withUser(&quot;admin&quot;).password(new BCryptPasswordEncoder().encode(&quot;blabla&quot;)).roles(&quot;ADMIN&quot;);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .antMatchers(&quot;/&quot;).permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}

答案1

得分: 2

我怀疑这是否可能,因为API文档是在启动时生成的(我认为)。

相反,您可以添加文档,指定哪些API调用需要哪些安全凭据,我在https://github.com/springdoc/springdoc-openapi#adding-api-information-and-security-documentation 找到了相关提及。

因此,如果用户能够查看API页面,那么它可能也会看到它无法访问的端点(例如/admin),但您可以添加文档说明只有管理员才能访问该端点。

英文:

I doubt whether this is possible as the API documentation is generated at startup time (I think).

What you can do instead is to add documentation specifying which security credentials are needed for which API calls, I found a mention of this at https://github.com/springdoc/springdoc-openapi#adding-api-information-and-security-documentation

So if a user is able to see the API page, then it might also see the endpoints it does not have access to (such as /admin), but you could add documentation to it that the endpoint can only be accessed by admins.

答案2

得分: 1

根据您提供的描述,我建议如下。

  1. 在端点上添加特定角色的安全性:

例如:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/rest/admin/**").hasAnyRole("ADMIN").and()
        .httpBasic()
            .and()
        .csrf().disable();   
}
  1. @PreAuthorize中添加'ROLE_'

例如:

@PreAuthorize("hasRole('ROLE_USER')")

或者

@PreAuthorize("hasRole('ROLE_ADMIN')")

然后它应该按预期工作。

另外,如果仍然不按预期工作,我建议根据超级角色(在您的情况下是ADMIN)为每个角色创建两个单独的GroupedOpenApi,并根据路径标识符将API分隔开,并在相应的antMatchers上创建相应的安全配置(例如:.antMatchers("/rest/admin/**").hasAnyRole("ADMIN"))。
这样,您可以根据角色在路径上配置安全性,并为文档创建单独的GroupedOpenApi

附注:我建议首先尝试第一种方法,只有在需要时再使用第二种方法。

英文:

Based on the description you have provided, I would recommend the following.

  1. Add Role specific security on endpoints:

e.g.:

@Override
protected void configure(HttpSecurity http) throws Exception {
http
      .authorizeRequests()
        .antMatchers(&quot;/rest/admin/**&quot;).hasAnyRole(&quot;ADMIN&quot;).and()
      .httpBasic()
        .and()
    .csrf().disable();   
}
  1. Add the 'ROLE_' to your @PreAuthorize

e.g.:

@PreAuthorize(&quot;hasRole(&#39;ROLE_USER&#39;)&quot;)

or

@PreAuthorize(&quot;hasRole(&#39;ROLE_ADMIN&#39;)&quot;)

It should then work as expected.

Additionally, if it still doesn't work as expected, I would suggest to create two separate GroupedOpenApi per role and to segregate the apis by path identifier for the super role (i.e. ADMIN in your case) and create respective security configurations on respective antMatchers (e.g.: .antMatchers(&quot;/rest/admin/**&quot;).hasAnyRole(&quot;ADMIN&quot;)).
This should work then work as you are configuring the security on paths per role as well as configuring separate GroupedOpenApi for documentation.

P.S.: I would first try the 1st approach and only use the 2nd as fallback.

huangapple
  • 本文由 发表于 2020年8月5日 01:31:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/63252180.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定