spring-boot 在单个 Web 应用程序路径上设置基本身份验证?

Posted

技术标签:

【中文标题】spring-boot 在单个 Web 应用程序路径上设置基本身份验证?【英文标题】:spring-boot setup basic auth on a single web app path? 【发布时间】:2014-08-30 18:01:01 【问题描述】:

我正在尝试在基于 spring-boot spring MVC 的应用程序中设置单个路径 (/basic) 以进行基本身份验证保护。我将使用我自己的自定义配置参数进行配置,因此用户名和密码只是“admin”和“admin”。

这目前适用于 /basic 路径(我收到提示并且可以正确登录)。问题是注销不起作用(我不确定为什么),并且其他路径(如 /other 显示)被要求提供基本身份验证凭据(在总是被拒绝之前)。

static class MyApplicationSecurity extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests().antMatchers("/open").permitAll();
        http.authorizeRequests().antMatchers("/other").denyAll(); // Block it for now
         http.authorizeRequests().antMatchers("/basic").authenticated().and().httpBasic().and().logout().logoutUrl("/basic/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
    

我希望 /other 总是被拒绝,但我不明白为什么要提出基本身份验证。 /open 按预期工作。我也不明白为什么 /basic/logout 不会让我退出(它也不会产生错误消息)。我确实有一些简单的代码作为注销端点的占位符,但如果没有,我会得到 404。“主页”视图是我的 Web 应用程序根目录,所以我只想在注销后将用户发送到那里。

@RequestMapping("/logout")
public ModelAndView logout() 
    // should be handled by spring security
    return new ModelAndView("home");

更新: 这是最终似乎有效的解决方案(除了注销部分,仍然无效):

@Configuration
@Order(1) // HIGHEST
public static class OAuthSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.antMatcher("/oauth").authorizeRequests().anyRequest().denyAll();
    


@Configuration
public static class BasicAuthConfigurationAdapter extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.antMatcher("/basic").authorizeRequests().anyRequest().authenticated().and().httpBasic();
        http.logout().permitAll().logoutUrl("/logout").logoutSuccessUrl("/").invalidateHttpSession(true);
        //.and().logout().logoutUrl("/basic/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
    

【问题讨论】:

【参考方案1】:

我不确定注销的情况,但我们遇到了类似的问题,即我们的一些网站处于基本状态,而有些则没有。我们的解决方案是仅对需要 http basic 的路径使用第二个嵌套配置类。我们给这个配置一个@Order(1)..但我不确定这是否有必要。

更新代码

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig 
    private static final Logger LOG = LoggerFactory.getLogger(SecurityConfig.class);

    @Autowired
    public void registerAuthentication(AuthenticationManagerBuilder auth, Config appConfig) throws Exception 
        auth.inMemoryAuthentication()
            .withUser(appConfig.getString(APIConfig.CONFIG_KEY_MANAGEMENT_USER_NAME))
            .password(appConfig.getString(APIConfig.CONFIG_KEY_MANAGEMENT_USER_PASS))
            .roles(HyperAPIRoles.DEFAULT, HyperAPIRoles.ADMIN);        
    



    /**
     * Following Multiple HttpSecurity approach:
     * http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity 
     */
    @Configuration
    @Order(1)
    public static class ManagerEndpointsSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(HttpSecurity http) throws Exception 
            http
            .antMatcher("/management/**").authorizeRequests().anyRequest().hasRole(HyperAPIRoles.ADMIN).and()
            .httpBasic();
        
    

    /**
     * Following Multiple HttpSecurity approach:
     * http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity 
     */
    @Configuration
    public static class ResourceEndpointsSecurityConfig extends WebSecurityConfigurerAdapter         



       @Override
       protected void configure(HttpSecurity http) throws Exception                   

            http
            //fyi: This adds it to the spring security proxy filter chain
            .addFilterBefore(createBBAuthenticationFilter(), BasicAuthenticationFilter.class)
            ;      
       
    

这似乎使用基本身份验证保护 /management 处的执行器端点,而其他端点使用自定义身份验证令牌标头。我们不会提示输入凭据(没有发出任何挑战),但对于任何事情..我们必须注册一些其他的东西才能做到这一点(如果我们想要的话)。

希望对你有帮助

【讨论】:

所以你有 2 个 WebSecurityConfigurerAdapter(或类似的东西)? 太棒了。我使用了我在上面的问题中提出的变体。我仍然无法让注销部分正常工作。不过,我会投票赞成你的答案,因为它帮助我解决了部分问题。 为什么需要注销 HTTP 基础版? HTTP 表单注销您可以继续进行正常设置。一个完整的例子可以在这个链接中看到。 ***.com/questions/27774742/…【参考方案2】:

只有一条路径会受到保护

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception
    
        auth.inMemoryAuthentication()
                .withUser("user").password(passwordEncoder().encode("user"))
                .roles("USER");
    

    @Configuration
    @Order(1)
    public static class ManagerEndpointsSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(HttpSecurity http) throws Exception 
            http.authorizeRequests()
                    .antMatchers("/add/**").authenticated()
                    .anyRequest().permitAll()
                    .and()
                    .httpBasic()
                    .and().csrf().disable();
        
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

【讨论】:

以上是关于spring-boot 在单个 Web 应用程序路径上设置基本身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring-boot 存储库返回单个属性

在 spring-boot Web 应用程序中未考虑 web.xml 会话超时?

Heroku H14(没有运行 Web 进程)+ Spring-boot

使用 web.xml 配置 spring-boot 应用程序

Spring-boot之jQuery File Upload后台配置方法

spring-boot实战07:Spring Boot中Web应用的统一异常处理