簡體   English   中英

Spring Security,禁用 REST 請求的 formLogin()

[英]Spring Security, disable formLogin() for REST requests

我正在使用 Spring Boot、Spring Security、Spring Data REST、Hibernate。 我正在創建一個 REST API 服務器。

我將安全性配置為訪問我的 REST API:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@CrossOrigin(origins = "*")
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private TenantFilter tenantFilter;


    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(this.userDetailsService).passwordEncoder(User.PASSWORD_ENCODER);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtTokenFilter() throws Exception {
        return new JwtAuthenticationTokenFilter();
    }

    @Bean
    public CookieAuthFilter cookieAuthFilter() throws Exception {
        return new CookieAuthFilter();
    }

    @Bean
    public CustomWebAuthenticationDetailsSource customWebAuthenticationDetailsSource() {
        return new CustomWebAuthenticationDetailsSource();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //********************************************************************
                // PERMIT OPTIONS
                //********************************************************************
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

                //********************************************************************
                //WEBSOCKET
                //********************************************************************
                .antMatchers("/socket/**").permitAll()

                .antMatchers("/images/**").permitAll()

                .antMatchers("/resources/templates/**").permitAll()

                .antMatchers("/api/v1/notifications/**").permitAll()

                //********************************************************************
                // SWAGGER
                //********************************************************************
                .antMatchers("/v2/api-docs", "/swagger-accounts/configuration/ui", "/swagger-accounts", "/swagger-accounts/configuration/security",
                        "/swagger-ui.html", "/webjars/**", "/swagger-resources/**").permitAll()


                .antMatchers("/api/v1/").permitAll()

                .antMatchers("/api/v1/auth/**").permitAll()
                .antMatchers("/api/v1/formLogin/**").permitAll()

                .antMatchers("/api/v1/logout").permitAll()

                .antMatchers("/api/v1/agents/verifyEmail").permitAll()

                .antMatchers("/api/v1/agents/**/verificationToken").permitAll()

                .antMatchers("/api/v1/agents/**/resetPassword").permitAll()

                .antMatchers("/api/v1/agents/**/verifyPasswordReset").permitAll()

                .antMatchers("/api/v1/agents/**/changePassword").permitAll()

                .antMatchers("/api/v1/errors/**").permitAll()

                .antMatchers("/api/v1/verifyCaptcha").permitAll()

                .antMatchers("/api/v1/ping").permitAll()

                .antMatchers("/api/v1/tenants/**").permitAll()

                // all other endpoints are authenticated
                .antMatchers("/**").authenticated()

                // global settings
                .and()
                .csrf()
                .disable();

       http.formLogin().loginPage("/login").permitAll();


        // Custom JWT based security filter
        http.addFilterBefore(tenantFilter, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(cookieAuthFilter(), UsernamePasswordAuthenticationFilter.class);

        http.headers().cacheControl().disable();
    }
}

我想要達到的目標是:

  • 當用戶嘗試訪問像http://myhost/swagger-ui.html#/這樣的 url 時顯示表單登錄,以便能夠輕松使用 swagger

  • 當使用 REST 調用(通過 Angular 或 Postman 或其他方式)調用服務器時,避免表單登錄。 其實不然,如果auth失敗,服務器回復登錄頁面的html代碼

有沒有辦法在不關閉 formLogin() 的情況下使用 Spring 完成此操作?

其他配置看起來不錯

如果您注意到 swagger 相關的 url 也被標記為permitAll().

只需刪除 swagger 的 permitAll 部分並將其添加到最后作為身份驗證()這樣的東西

.antMatchers("/v2/api-docs", "/swagger-accounts/configuration/ui", "/swagger-accounts", "/swagger-accounts/configuration/security",
                        "/swagger-ui.html", "/webjars/**", "/swagger-resources/**").authenticated()

對於 REST 調用,只需查看是否將它們添加到permitAll()

另請注意:規則的順序很重要,更具體的規則應該先行

例如

.antMatchers("/admin/**").authenticated()
.antMatchers("/admin/login").permitAll()

這里/admin/login也將被認證。

看看結合基本身份驗證和表單登錄為同一個 REST Api ,我相信它滿足您的要求。

我認為您可能需要更改的唯一一件事是在ApiWebSecurityConfigurationAdapter因為您只詢問 403,內容應如下所示(如果您不喜歡它太嚴格,可以將hasRole(String...)替換為authenticated() ) .

http.antMatcher("/api/**").authorizeRequests().anyRequest().hasRole("ADMIN")

我不知道你是否或如何解決這個問題,但我正在尋找類似的東西。 所以對於任何也在尋找這個的人,我的想法是:

您可以配置 2 個 HttpSecurity 元素 所以你擴展了 WebSecurityConfigurerAdapter 2 次。 讓你的端點像這樣:

  • '/view/**/*' 用於需要表單登錄的所有內容
  • '/api/**/*' 對於所有需要 403 的東西

然后在一個安全配置中使用 .formlogin() 配置 /view/ 在另一個安全中不要配置 .formlogin()

可以在此處找到一個應用程序中 2 個 securityConfig 的示例: https : //www.baeldung.com/spring-security-two-login-pages但是在那篇文章中,他們使用它來顯示 2 個不同的登錄頁面,您可以使用這在一種情況下不顯示表單登錄...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM