Java 针对特定终结点的多个安全配置

Java 针对特定终结点的多个安全配置,java,spring,spring-security,Java,Spring,Spring Security,我想知道是否有一种方法可以提供两种不同类型的身份验证? 用户应使用基本身份验证来记录、注册、获取端点的用户数据/login、/register、/User。当我调用/api时,它应该只使用头中提供的JWT令牌进行身份验证 但是,当我调用/api时,我会在没有任何身份验证的情况下获取所有数据。当用户登录并调用/user时,API允许JWT访问/API 我的代码: 基本身份验证的配置: @Configuration @EnableWebSecurity @Order(1) public class

我想知道是否有一种方法可以提供两种不同类型的身份验证? 用户应使用基本身份验证来记录、注册、获取端点的用户数据
/login
/register
/User
。当我调用
/api
时,它应该只使用头中提供的JWT令牌进行身份验证

但是,当我调用
/api
时,我会在没有任何身份验证的情况下获取所有数据。当用户登录并调用
/user
时,API允许JWT访问
/API

我的代码:

基本身份验证的配置:

@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors()
                .and()
            .csrf().disable();
        http
            .authorizeRequests()
                .antMatchers("/user").authenticated()
                .antMatchers("/register").permitAll()
                .and()
            .formLogin().permitAll()
                .defaultSuccessUrl("/user");
    }
JWT auth的配置:

@Configuration
@Order(2)
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .antMatcher("/api/**")
            .addFilterAfter(new JWTAuthorizationFilter(),UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .httpBasic().disable();
    }

我也有同样的问题,我想要一些端点的基本身份验证,而对于其他端点,我想要其他身份验证方法。就像你的一样。您需要对一些端点进行基本身份验证(
/login
/register
/user
),并对其他端点进行JWT身份验证(
/api/**

我使用了一些关于多个的教程,但它不起作用。

这是我的解决方案(它奏效了) 通过创建自定义筛选器,将基本身份验证与JWT身份验证分开

  • 为应使用基本身份验证进行身份验证的端点添加前缀路径。比如: (
    /basic/login
    /basic/register
    /basic/user

  • /basic
    前缀(用于
    /basic
    请求)创建新的自定义筛选器,并检查基本身份验证

    @Component
    public class BasicAuthenticationFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    
        //Check for the requests that starts with /basic 
        if (httpServletRequest.getRequestURI().startsWith("/basic/")) {
    
            try {
                //Fetch Credential from authorization header
                String authorization = httpServletRequest.getHeader("Authorization");
                String base64Credentials = authorization.substring("Basic".length()).trim();
                byte[] credDecoded = Base64.getDecoder().decode(base64Credentials);
                String credentials = new String(credDecoded, StandardCharsets.UTF_8);
                final String username = credentials.split(":", 2)[0];
                final String password = credentials.split(":", 2)[1];
    
                //Check the username and password
                if (username.equals("admin") && password.equals("admin")) {
                    //continue
                    chain.doFilter(request, response);
                } else
                    throw new AuthenticationCredentialsNotFoundException("");
            } catch (Exception e) {
                throw new AuthenticationCredentialsNotFoundException("");
            }
    
        } else chain.doFilter(request, response);
    
      }
    
    }
    
  • 只为JWT编写主安全配置并允许
    /basic
    URL

    @Configuration
    @EnableWebSecurity
    public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
    
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/basic/**").permitAll().and()
                .csrf().disable()
                .antMatcher("/api/**")
                .addFilterAfter(new JWTAuthorizationFilter(),UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic().disable();
    }
    

  • 我也有同样的问题,我想要一些端点的基本身份验证,而对于其他端点,我想要其他身份验证方法。就像你的一样。您需要对一些端点进行基本身份验证(
    /login
    /register
    /user
    ),并对其他端点进行JWT身份验证(
    /api/**

    我使用了一些关于多个的教程,但它不起作用。

    这是我的解决方案(它奏效了) 通过创建自定义筛选器,将基本身份验证与JWT身份验证分开

  • 为应使用基本身份验证进行身份验证的端点添加前缀路径。比如: (
    /basic/login
    /basic/register
    /basic/user

  • /basic
    前缀(用于
    /basic
    请求)创建新的自定义筛选器,并检查基本身份验证

    @Component
    public class BasicAuthenticationFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    
        //Check for the requests that starts with /basic 
        if (httpServletRequest.getRequestURI().startsWith("/basic/")) {
    
            try {
                //Fetch Credential from authorization header
                String authorization = httpServletRequest.getHeader("Authorization");
                String base64Credentials = authorization.substring("Basic".length()).trim();
                byte[] credDecoded = Base64.getDecoder().decode(base64Credentials);
                String credentials = new String(credDecoded, StandardCharsets.UTF_8);
                final String username = credentials.split(":", 2)[0];
                final String password = credentials.split(":", 2)[1];
    
                //Check the username and password
                if (username.equals("admin") && password.equals("admin")) {
                    //continue
                    chain.doFilter(request, response);
                } else
                    throw new AuthenticationCredentialsNotFoundException("");
            } catch (Exception e) {
                throw new AuthenticationCredentialsNotFoundException("");
            }
    
        } else chain.doFilter(request, response);
    
      }
    
    }
    
  • 只为JWT编写主安全配置并允许
    /basic
    URL

    @Configuration
    @EnableWebSecurity
    public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
    
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/basic/**").permitAll().and()
                .csrf().disable()
                .antMatcher("/api/**")
                .addFilterAfter(new JWTAuthorizationFilter(),UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic().disable();
    }
    

  • 我遵循了spring docs(),但我不知道我的代码有什么问题,如果你想对每个请求进行身份验证,你必须禁用HTTP会话。我遵循了spring docs(),但我不知道我的代码有什么问题,如果你想对每个请求进行身份验证,你必须禁用HTTP会话。