简体   繁体   English

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

[英]spring-boot setup basic auth on a single web app path?

I am trying to setup a single path (/basic) in my spring-boot spring MVC based application to be basic auth protected.我正在尝试在基于 spring-boot spring MVC 的应用程序中设置单个路径 (/basic) 以进行基本身份验证保护。 I am just going to configure this using my own custom configuration parameters so the username and password are simply "admin" and "admin".我只是要使用我自己的自定义配置参数来配置它,因此用户名和密码只是“admin”和“admin”。

This currently works for the /basic path (I am prompted and can login correctly).这目前适用于 /basic 路径(我得到提示并且可以正确登录)。 The problem is that logout does not work (and I am not sure why) and also other paths (like /other shown) are being asked for basic auth credentials (before always being denied).问题是注销不起作用(我不知道为什么)并且还要求其他路径(如 /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("/");
    }
}

I expected /other to always be denied but I don't get why basic auth is coming up for it.我希望 /other 总是被拒绝,但我不明白为什么会出现基本身份验证。 /open works as expected. /open 按预期工作。 I also don't understand why /basic/logout does not log me out (it also does not produce error messages).我也不明白为什么 /basic/logout 不会让我退出(它也不会产生错误消息)。 I do have a simple bit of code as a placeholder for the logout endpoint but if I do not have that then I get a 404. The "home" view is my web app root so I just want to send the user there after logout.我确实有一些简单的代码作为注销端点的占位符,但如果我没有它,那么我会得到 404。“主页”视图是我的 Web 应用程序根,所以我只想在注销后将用户发送到那里。

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

UPDATE: Here is the solution that seemed to work in the end (except the logout part, still not working):更新:这是最终似乎有效的解决方案(除了注销部分,仍然无效):

@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("/");
    }
}

i'm not sure about the logout, but we had a similar problem with having some of our site under basic and some of it not.我不确定注销,但我们遇到了类似的问题,我们的一些网站处于基本状态,而有些则不是。 Our solution was to use a second nested configuration class only for the paths that needed http basic.我们的解决方案是仅对需要 http basic 的路径使用第二个嵌套配置类。 We gave this config an @Order(1)..but i'm not sure if that was necessary or not.我们给这个配置一个@Order(1)..但我不确定这是否有必要。

Updated with code用代码更新

@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)
            ;      
       }
    }
}

this seems to secure the actuator endpoints at /management with basic auth while the others work with a custom auth token header.这似乎使用基本身份验证保护 /management 处的执行器端点,而其他人使用自定义身份验证令牌标头。 We do not prompt for credentials (no challenge issued) though for anything..we'd have to register some other stuff to get that going (if we wanted it).我们不会提示输入凭据(没有发出任何挑战),但我们必须注册一些其他东西才能实现(如果我们想要的话)。

Hope this helps希望这可以帮助

only one path will be protected只有一条路径会受到保护

@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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM