#spring-boot #spring-security #http-status-code-401
#spring-boot #spring-security #http-status-code-401
Вопрос:
У меня есть конечная точка REST приложения Spring boot 2, как показано ниже
@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
Пожалуйста, обратите внимание: это перестало работать после внесения следующих изменений в приложение:
-
Введение класса CORSConfig
-
Удаление зависимости gradle
compile group: 'org.springframework.security', name: 'spring-security-ldap', version: '5.1.2.RELEASE'
-
Включен класс AuthEntryPoint для фиксации ошибки 401
Пожалуйста, посоветуйте, что я здесь делаю не так, заранее спасибо
Ответ №1:
Вы получаете ошибку 401. Это означает, что URL, к которому вы пытаетесь получить доступ, защищен. Поскольку вы говорите, что предоставили действительные учетные данные пользователя, то, возможно, у пользователя нет роли «APP_GP_USER»?
Я вижу, что вы передаете конфиденциальную информацию, такую как идентификатор клиента / секрет клиента, как часть URL-адреса запроса. Вероятно, вам следует пересмотреть это.
Передает ли клиент заголовок авторизации в запросе на удаление? Вам необходимо предоставить это, поскольку вы включили базовую аутентификацию в своем файле WebSecurityConfig через httpBasic() в методе configure.
Я бы посоветовал вам протестировать свои URL-адреса с помощью http-клиента, такого как postman.
Например, здесь я пытаюсь получить доступ к защищенному URL: http://localhost:8088/demo/home без предоставления базовой аутентификации. Обратите внимание, я получаю ошибку 401.
И здесь я предоставил надлежащие учетные данные и поэтому получил правильный ответ. Обратите внимание, как postman добавил заголовок авторизации.
Комментарии:
1. Спасибо за подсказку, Навин, я добавил .httpBasic().disable(), чтобы api не применял базовую аутентификацию и включил пользовательский обработчик для отслеживания ошибок 403, поскольку httpbasic отключен, мы не должны ожидать 401. Я попросил команду пользовательского интерфейса передать роль в URL, чтобы проверить это