Я пытался выяснить это в течение нескольких недель и был в замешательстве.
Мы пытаемся перейти на SSO, и у меня возникают некоторые проблемы, когда шлюз отправляет токен нисходящему сервису. Аутентификация отлично работает в шлюзе, и я могу правильно просматривать аутентифицированного пользователя в контексте Spring.
Я использую Spring Boot 2.2.0.
Когда запрос попадает в нисходящий поток, я я получаю сообщение об ошибке
There was an unexpected error (type=Internal Server Error, status=500).
Signed JWT rejected: Invalid signature
com.nimbusds.jose.proc.BadJWSException: Signed JWT rejected: Invalid signature
at com.nimbusds.jwt.proc.DefaultJWTProcessor.<clinit>(DefaultJWTProcessor.java:103)
at com.microsoft.azure.spring.autoconfigure.aad.UserPrincipalManager.getAadJwtTokenValidator(UserPrincipalManager.java:94)
at com.microsoft.azure.spring.autoconfigure.aad.UserPrincipalManager.buildUserPrincipal(UserPrincipalManager.java:85)
at com.microsoft.azure.spring.autoconfigure.aad.AADAuthenticationFilter.doFilterInternal(AADAuthenticationFilter.java:78)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
Прежде чем я начну разбираться с тем, что я узнал благодаря отладке, позвольте мне показать вам все настройки, которые есть в моих приложениях:
Spring Gateway:
Application.properties
spring.security.oauth2.client.registration.azure.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.azure.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.azure.scope=User.read
spring.security.oauth2.client.registration.azure.client-id=<<<My client ID>>>
spring.security.oauth2.client.registration.azure.client-secret=<<<My secret>>>
spring.security.oauth2.client.provider.azure.issuer-uri=https://login.microsoftonline.com/<<<Tenant id>>>/v2.0
azure.activedirectory.tenant-id=<<<Tenant id>>>
azure.activedirectory.active-directory-groups=Bench,Internal Projects
spring.cloud.gateway.routes[0].id=<<<App ID>>>
spring.cloud.gateway.routes[0].uri=<<<App URI>>>
spring.cloud.gateway.routes[0].predicates[0]=Path=<<<Path>>>
spring.cloud.gateway.routes[0].filters[0]=RewritePath=<<<Rewrit Path>>>
spring.cloud.gateway.default-filters[0]=TokenRelay
SecurityConfig
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeExchange()
.pathMatchers("/eureka/**").hasAnyAuthority("SUPER_ADMIN")
.anyExchange().authenticated()
.and()
.oauth2Login();
return http.build();
Dependencies:
dependencies {
implementation "io.jsonwebtoken:jjwt:0.7.0"
implementation "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
implementation "org.glassfish.jaxb:jaxb-runtime:2.3.2"
compile "org.springframework.security:spring-security-oauth2-client"
compile "com.microsoft.azure:azure-active-directory-spring-boot-starter:2.2.2"
implementation "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-starter-security"
implementation "org.springframework.boot:spring-boot-starter-data-redis"
implementation "org.springframework.cloud:spring-cloud-starter-gateway"
implementation "org.springframework.cloud:spring-cloud-starter-security"
implementation "org.springframework.cloud:spring-cloud-starter-consul-all"
implementation "org.springframework.cloud:spring-cloud-starter-config"
implementation "redis.clients:jedis:3.1.0"
С этим В конфигурации в контексте Spring устанавливается контекст, путь попадает в правильный API и конечную точку и передает access_token вниз по течению в мою службу
Теперь для моего нижестоящего API:
Application.properties
azure.activedirectory.client-id=<<<ID>>>
azure.activedirectory.client-secret=<<<Secret>>>
SecurityConfig
@Autowired
private AADAuthenticationFilter aadAuthFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests().anyRequest().permitAll()
.and()
.addFilterBefore(aadAuthFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(globalAuthEntryPoint);
}
Вот мои настройки. Я также попытался добавить это в мои application.properties: spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.microsoftonline.com/common/discovery/keys
(я также пробовал конечную точку v2.0)
И когда я это делаю, я получаю эту ошибку:
Thu Jan 23 15:40:36 EST 2020
There was an unexpected error (type=Internal Server Error, status=500).
Signed JWT rejected: Invalid signature
com.nimbusds.jose.proc.BadJWSException: Signed JWT rejected: Invalid signature
at com.nimbusds.jwt.proc.DefaultJWTProcessor.<clinit>(DefaultJWTProcessor.java:103)
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder$JwkSetUriJwtDecoderBuilder.processor(NimbusJwtDecoder.java:283)
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder$JwkSetUriJwtDecoderBuilder.build(NimbusJwtDecoder.java:298)
at org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration$JwtDecoderConfiguration.jwtDecoderByJwkKeySetUri(OAuth2ResourceServerJwtConfiguration.java:68)
Из того, что я понимаю, предполагается, что нисходящий сервис будет вызывать Microsoft Graph для получения информации о пользователях / полномочий и установки их в контексте Spring. Похоже, что он не работает в фильтре прямо перед этим.
Может кто-нибудь помочь мне разобраться в этом Azure материале?