Spring Security HTTP Basic for RESTFul and FormLog

2019-01-10 05:12发布

In Specific

I want to have HTTP Basic authentication ONLY for a specific URL pattern.

In Detail

I'm creating an API interface for my application and that needs to be authenticated by simple HTTP basic authentication. But other web pages should not be using HTTP basic but rather a the normal form login.

Current Configuration - NOT Working

@Override
protected void configure(HttpSecurity http) throws Exception {
    http //HTTP Security
            .csrf().disable() //Disable CSRF
            .authorizeRequests() //Authorize Request Configuration
                .antMatchers("/connect/**").permitAll()
                .antMatchers("/", "/register").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/api/**").hasRole("API")
                .anyRequest().authenticated()
            .and() //HTTP basic Authentication only for API
                .antMatcher("/api/**").httpBasic()
           .and() //Login Form configuration for all others
                .formLogin().loginPage("/login").permitAll()
            .and() //Logout Form configuration
                .logout().permitAll();

}

2条回答
放我归山
2楼-- · 2019-01-10 05:46

I dunno if it can be helpful but I couldn't implement the above solution. I found a workaround defining a single Security

@Configuration class

extending

WebSecurityConfigurerAdapter

with both httpBasic() and formLogin() configured. Then I created a custom

CustomAuthEntryPoint implements AuthenticationEntryPoint

that has this logic in the commence method:

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
   {
        String urlContext = UtilityClass.extractUrlContext(request);
        if (!urlContext.equals(API_URL_PREFIX))
        {
            String redirectUrl = "urlOfFormLogin"
            response.sendRedirect(request.getContextPath() + redirectUrl);
       }
        else
        {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }

Dunno which is the "best practice strategy" about this issue

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-10 05:52

Waited for 2 days and didn't get any help here. But my research provided me a solution :)

Solution

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private AuthenticationProvider authenticationProvider;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .antMatcher("/api/**")
                    .authorizeRequests()
                        .anyRequest().hasAnyRole("ADMIN", "API")
                        .and()
                    .httpBasic();
        }
    }

    @Configuration
    @Order(2)
    public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/lib/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable() //HTTP with Disable CSRF
                    .authorizeRequests() //Authorize Request Configuration
                        .antMatchers("/connect/**").permitAll()
                        .antMatchers("/", "/register").permitAll()
                        .antMatchers("/admin/**").hasRole("ADMIN")
                        .anyRequest().authenticated()
                        .and() //Login Form configuration for all others
                    .formLogin()
                        .loginPage("/login").permitAll()
                        .and() //Logout Form configuration
                    .logout().permitAll();
        }
    }
}
查看更多
登录 后发表回答