Spring Security抛出401错误,并带有有效的客户端ID和客户端密码

问题描述

我有一个spring boot 2 app REST端点,如下所示

@DeleteMapping(value = "/deleteUser",produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity deleteUser(HttpServletRequest pRequest,@RequestParam(value = "userId",required = true) String userId) {
    if (validateRequest(userId)) {
        try {
            response = myService.deleteUser(userId);
        } catch (Exception e) {
            logger.error("Exception");
        }
    } else {
        response = new ResponseEntity("Invalid user request.",new HttpHeaders(),HttpStatus.FORBIDDEN);
    }

    return response;
}

应用没有强制执行基本身份验证,但对端点有限制。 客户端正在使用有效的凭据调用URL:

deleteUserUrl=https://xxxx,clientId=xxxx,clentSecret=xxx

得到错误

Full authentication is required to access this resource 

这是我的WebSecurityConfig文件。此访问仅限于某些角色。

  @Configuration
  @EnableWebSecurity
  public class WebSecurityConfig extends WebSEALSecurityConfig
 {

    @Value("${ldap.server.admin.group}")
    private String SERVER_ADMIN_GROUP;

    @Value("${app.user.group}")
    private String APP_GP_USER;

    @Autowired
    private AuthEntryPoint unauthorizedHandler; 
    //This class just to capture 401 error

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
           httpSecurity
             .authorizeRequests()
             .antMatchers(HttpMethod.OPTIONS,"/**").permitAll()
             .antMatchers("/actuator/health").permitAll()
             .antMatchers("/actuator/**").hasRole(SERVER_ADMIN_GROUP)
             .antMatchers("/test/deleteUser").hasRole(APP_GP_USER)
             .and().addFilterBefore(getCmpAuthenticationSelectionFilter(),BasicAuthenticationFilter.class)
              .httpBasic()
              .authenticationEntryPoint(unauthorizedHandler)
             .and().csrf().disable()
            . sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
         }
     }

这是我的CORS过滤器类:

@Configuration
public class CORSConfig {
    @Bean
    public CorsFilter corsFilter() {    
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**",config);
        return new CorsFilter(source);
    }
}

这是我的gradle文件

  plugins {
     id 'org.springframework.boot' version '2.1.6.RELEASE'
     id 'java'
  }

  apply plugin: 'io.spring.dependency-management'
  apply plugin: 'java'
  apply plugin: 'eclipse'
  apply plugin: 'org.springframework.boot'
  apply plugin: 'jacoco'
  apply plugin: 'checkstyle'
  apply plugin: 'jdepend'

  sourceCompatibility = 1.11

  dependencies {
    implementation('org.springframework.boot:spring-boot-starter')
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-cache')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-mail')
    implementation "com.company:webauth-plugin:2.0.1"
    implementation('org.springframework.boot:spring-boot-starter-security')

    compile('org.springframework.boot:spring-boot-starter-jdbc') {
       exclude group: 'org.apache.tomcat',module: 'tomcat-jdbc'
    }

    compile('org.apache.commons:commons-lang3:3.5')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.apache.commons:commons-collections4:4.0')
    compile group: 'net.minidev',name: 'json-smart',version: '1.0.9'
    compile group: 'net.sf.jt400',name: 'jt400-jdk8',version: '9.5'
    compile('org.apache.httpcomponents:httpclient:4.3.4')
    compileOnly 'org.projectlombok:lombok'
    runtime('com.microsoft:sqljdbc4:4.0')

    testCompile group: 'org.springframework.boot',name: 'spring-boot-starter-test'
    testCompile group: 'junit',name: 'junit'

 }

application.properties文件

  app.environment=${APP_ENV}
  server.servlet.context-path=${SERVER_CONTEXT_PATH}
  server.port=${SERVER_PORT}

  management.endpoints.web.exposure.include=*
  management.endpoint.shutdown.enabled=true
  management.health.ldap.enabled=false
  management.endpoints.web.cors.allow-credentials=true

请注意:在对应用程序进行以下更改后,此操作将停止工作:

  1. CORSConfig类的介绍

  2. 删除gradle依赖项

     compile group: 'org.springframework.security',name: 'spring-security-ldap',version: '5.1.2.RELEASE'
    
  3. 包含的AuthEntryPoint类可捕获401错误

在这里,请先告知我我在做什么错

解决方法

您收到401错误。这意味着您尝试访问的URL受保护。既然,您是说您提供了有效的用户证书,那么该用户可能没有“ APP_GP_USER”角色?

我看到您正在将敏感信息(例如客户ID /客户机密)作为请求url的一部分传递。您可能应该重新考虑一下。

客户端是否在删除请求中传递了Authorization标头?您需要提供此信息,因为您已经通过configure方法中的httpBasic()在WebSecurityConfig文件中启用了基本身份验证。

我建议您使用诸如邮递员之类的http客户端来测试您的网址。

例如,在这里我尝试访问受保护的URL:http:// localhost:8088 / demo / home,但不提供基本身份验证。注意,我收到401错误。

401 error

在这里,我提供了适当的凭据,因此请获得适当的答复。请注意邮递员如何添加授权标头。

Added basic auth

Success response