结合相同REST Api的基本身份验证和表单登录

时间:2015-11-16 15:50:55

标签: spring authentication spring-security

有没有办法为同一个REST服务设置基本身份验证和表单登录?我希望让登录用户在登录后通过Web浏览器和从运行curl -u username:password hostname.com/api/process的命令行启动此服务 现在我看过这篇文章:Basic and form based authentication with Spring security Javaconfig 但它与我试图做的略有不同。 有没有办法用弹簧设置它? 我现在拥有的是:

package com.my.company.my.app.security;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/js/**", "/css/**")
                .permitAll();

        http
                .authorizeRequests()
                .antMatchers("/api/**")
                .authenticated()
                .and()
                .httpBasic();

        http
                .authorizeRequests()
                .antMatchers("/","/index")
                .authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/j_spring_security_check")
                .defaultSuccessUrl("/monitor")
                .failureUrl("/login?error")
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/j_spring_security_logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll()
                .and()
                .csrf()
                .disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username=?")
                .authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username=?");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }
}

唯一的问题是,在调用hostname.com/indexhostname.com/时,它不会重定向到我的登录页面,而是要求提供基本身份验证凭据的窗口弹出窗口。

2 个答案:

答案 0 :(得分:23)

您可以使用多个http配置轻松实现此目的,此代码仅说明多个http配置。我假设你很清楚与spring security相关的其他基本配置,例如authenticationManger等。

    @EnableWebSecurity
    public class MultiHttpSecurityCustomConfig {
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().withUser("user").password("password").roles("USER").and().withUser("admin").password("password")
                    .roles("USER", "ADMIN");
        }

        @Configuration
        @Order(1)
        public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
            protected void configure(HttpSecurity http) throws Exception {
                http.antMatcher("/api/**").authorizeRequests().anyRequest().hasRole("ADMIN").and().httpBasic();
            }
        }

        @Configuration
        public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests().anyRequest().authenticated().and().formLogin();
            }


   }
}

请参阅春季安全官方链接:Multiple HttpSecurity

我还建议您查看Secure REST Services with Spring Security

如果您遇到任何问题,请随时发表评论!

答案 1 :(得分:1)

我发现,由于基本身份验证过滤器链中CSRF过滤器中的问题,先前的代码段在Spring Security 5中不起作用。可以通过为基本身份验证禁用CSRF使其工作。

顺便说一句,Form auth替代了Basic auth是因为此CSRF筛选器问题导致的重定向到/ error页面。

        @Configuration
        @Order(1)
        public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
            protected void configure(HttpSecurity http) throws Exception {
                http.antMatcher("/api/**")
                    .authorizeRequests()
                    .anyRequest()
                    .hasRole("ADMIN")
                    .and()
                    .httpBasic()
                    .csrf().disable();
            }
        }
相关问题