Приложение spring boot rest, защищенное keycloak 18, всегда возвращает ошибку 401 Неавторизованный
Я разрабатываю микросервисы, некоторые из них с веб-сайтом весенней загрузки, а другие с отдыхом данных весенней загрузки, и я хочу защитить их с помощью сервера keycloak 18 через протокол OpenId. Доступ к конечной точке микросервисов можно получить из внешнего интерфейса, добавив в «Заголовок авторизации» токен носителя, полученный из почтового запроса на URL-адрес http://localhost:8280/auth/realms/--realm_name--/.well-known/openid- конфигурация вставляя в тело запроса ключ client_id, имя пользователя, пароль, grant_type, client_secret.
Я создал 1. область, 2. клиент с именем «springboot-mc-dev» (с типом доступа = конфиденциальный, «Корневой URL-адрес» и «Действительные URI перенаправления», для которых установлено значение «http://localhost:8490» , «Стандартный поток включен», «Предоставление прямого доступа разрешено», «Учетные записи службы включены» и «Авторизация включена» установлены на «ВКЛ»),3. перед ролью внутри клиента (композит «named springboot-mc-dev-role» False) и после роли внутри области (всегда именуемой «springboot-mc-dev-role», составной true, которая связана с ролями клиента «springboot-mc-dev-role» клиента springboot-mc-dev),4.user отображается на роль «springboot-mc-dev-role» в «ролях области»
После того, как я импортировал следующую зависимость в родительский pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java-version>1.8</java-version>
<keycloak.version>18.0.2</keycloak.version>
</properties>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Вот код класса SecurityConfig.java
package it.organization.project.microservice.datamart.config.security;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@KeycloakConfiguration
@Configuration
@EnableWebSecurity
@Import(KeycloakSpringBootConfigResolver.class)
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@ConditionalOnProperty(name = "ms-security-enable", havingValue = "true")
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
grantedAuthorityMapper.setPrefix("ROLE_");
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
//keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
/*protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}*/
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/**").hasRole("springboot-mc-dev-role")
//.anyRequest().hasRole("springboot-mc-dev-role")
//.anyRequest().//authenticated()
//permitAll()
;
http.csrf().disable();
}
@Bean
public KeycloakConfigResolver KeycloakConfigResolver() {
//public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
это код основного класса
package it.organization.project.microservice.datamart;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class MAINDataMartApplication {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
SpringApplication.run(MAINDataMartApplication.class, args);
}
}
и последний файл application.yml с настройками keycloak
#KEYCLOAK CONFIGURATION
keycloak:
auth-server-url: http://localhost:8280/auth
#ssl-required: external
realm: realmname
bearer-only: true
#public-client: true
use-resource-role-mappings: true
resource: springboot-mc-dev
credentials:
secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
это результат
Что не так?
1 ответ
Адаптер весны Keycloak устарел . Не используйте его.
Посмотрите на эти учебники для альтернатив.
Нам не хватает важной информации, чтобы ответить точно:
- Весенние версии?
- причина 401 (из консоли Postman, значение
WWW-Authenticate
заголовок ответа)?
Может быть несколько причин для 401 Unauthorized:
- отсутствует заголовок авторизации
- просроченный или еще не действительный токен (например, из-за неправильной настройки часового пояса на сервере авторизации или ресурса)
- другой эмитент в заявке на токен доступа и конфигурация Spring: хост, порт и т. д. должны быть точно такими же
- Spring настроен для другого типа аутентификации, отличного от того, который поддерживает сервер авторизации (т. е. непрозрачный токен с интроспекцией с одной стороны и JWT с другой).
- ...
Если вы используете Keycloak 18 с Quarkus, вполне вероятно, что ваша конфигурация должна ссылатьсяhttp://localhost:8280
как эмитент (а неhttp://localhost:8280/auth
).
Итак, посмотрите на консоль Postman, откройте свой токен доступа с помощью такого инструмента, как https://jwt.io , и сравните значения, которые вы там найдете, с тем, что у вас есть в spring conf и журналах.