使用Azure AD,Spring Gateway和多个微服务进行身份验证

时间:2020-01-23 20:57:35

标签: java azure spring-boot oauth-2.0 azure-active-directory

我已经尝试了好几个星期了,很沮丧。

我们正在尝试迁移到SSO,当网关将令牌发送到下游服务时,我遇到了一些问题。身份验证在网关中工作正常,并且我能够在Spring Context中正确查看经过身份验证的用户。

我正在使用Spring Boot 2.2.0。

当请求向下游发送时,我收到了错误消息

Application.properties

在开始通过调试了解到目前为止所学的知识之前,让我向您展示我的应用程序中具有的所有配置:

Spring Gateway:

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"

Application.properties

使用此配置,将在网关中设置Spring Context,该路径将命中正确的API和端点,并将access_token下游传递给我的服务

现在,对于我的下游API:

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); }

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.microsoftonline.com/common/discovery/keys 

有我的设置。我也尝试通过将其添加到我的application.properties中: 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) (我也尝试过v2.0端点)

当我这样做时,会出现此错误:

// Get your element however you'd like
let myElmement = document.getElementById('myElement');
// Loop through possible events that will bring element into view
['resize','scroll','load'].forEach( eventName => {
  window.addEventListener(eventName, event => {
    if (isScrolledIntoView(myElmement)) {
      doYourThing();
    } else {
      console.log('nope');
    }
  });
});

// Borrowed from https://stackoverflow.com/a/22480938/12771340
function isScrolledIntoView(el) {
  let rect = el.getBoundingClientRect();
  let elemTop = rect.top;
  let elemBottom = rect.bottom;

  // Only completely visible elements return true:
  let isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
  // Partially visible elements return true:
  //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
  return isVisible;
}

据我了解,下游服务应该调用Microsoft Graph来获取用户信息/权限并在Spring Context中进行设置。看来它在过滤器失效之前就已经失败了。

有人可以帮我弄清楚这个Azure东西吗?

0 个答案:

没有答案