2

我有一个带有 Angular UI、Zuul 和一些与 Okta 登录 (OAuth) 集成的服务的应用程序(非响应式)。这工作正常,但在 jwt 令牌过期后卡住了。关于工作流程的一些细节

  1. 应用 URL 指向 Zuul。
  2. Zuul 将请求重定向到 Okta。用户登录。
  3. Okta 发回一个不记名令牌(也是一个刷新令牌)。
  4. 此不记名令牌被传递到 UI 并存储为 cookie。对于每个请求,UI 都会发送 Authorization 标头以及不记名令牌。
  5. 这个过程正常工作,直到 jwt 令牌在一小时内过期,然后 Zuul 尝试将其重定向到默认登录页面,因为我们使用 okta 登录,所以该页面没有任何内容。

我的问题

  1. 如果需要,可以将日志页面重定向到哪里https://dev1234.okta.com/oauth2/default?  
  2. 如何根据刷新令牌获取新的不记名令牌?
  3. 我可以根据刷新令牌在 Zuul 中自动获取新的不记名令牌吗?如果这不可能,最好的方法是什么?

这是 Zuul 的 application.yml 文件

spring:
  application:
    name: service-gateway
  cloud:
    loadbalancer:
      ribbon:
        enabled: false

server:
  port: 8080

okta:
  oauth2:
    issuer: https://dev1234.okta.com/oauth2/default
    client-id: <value>
    client-secret: <value>

    
feign:
  hystrix:
    enabled: true
hystrix:
  shareSecurityContext: true

eureka:
  client:
    enabled: true
    fetch-registry: true
    
zuul:
  routes:
    abc-service:
      path: /api/**
      strip-prefix: true
      service-id: ABC-SERVICE

    ui:
      path: /**
      url: http://localhost:4200
      
  host:
    connect-timeout-millis: 10000
    socket-timeout-millis: 20000
    
  sensitive-headers:
  - Cookie,Set-Cookie  

梯度文件

plugins {
    id 'org.springframework.boot' version '2.3.7.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    developmentOnly
    runtimeClasspath {
        extendsFrom developmentOnly
    }
}

repositories {
    mavenCentral()
}

ext {
    set('springCloudServicesVersion', "2.3.0.RELEASE")
    set('springCloudVersion', "Hoxton.SR9")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'com.okta.spring:okta-spring-boot-starter:1.4.0'
    implementation 'io.pivotal.spring.cloud:spring-cloud-services-starter-service-registry'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'io.pivotal.spring.cloud:spring-cloud-services-starter-config-client'
    implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

dependencyManagement {
    imports {
        mavenBom "io.pivotal.spring.cloud:spring-cloud-services-dependencies:${springCloudServicesVersion}"
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

test {
    useJUnitPlatform()
}

Zulu WebSecurityConfigurerAdapter

package abc
@EnableDiscoveryClient
@EnableZuulProxy
@SpringBootApplication

public class ServiceGateway {

    private static List<String> clients = Arrays.asList("okta");
    @Autowired
    private ClientRegistrationRepository clientRegistrationRepository;

    @Value("${okta.oauth2.client-id}")
    String clientId;
    @Value("${okta.oauth2.client-secret}")
    String clientSecret;

    public static void main(String[] args) {
        SpringApplication.run(ServiceGateway.class, args);
    }

    @Configuration
    static class OktaOAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .oauth2Login()
            .and()
            .oauth2ResourceServer().jwt();
            // @formatter:on
        }
    }

    @Bean
    public FilterRegistrationBean<CorsFilter> simpleCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.setAllowedMethods(Collections.singletonList("*"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }

    @Bean
    public OktaAuthenticationFilter oktaAuthFilter(OAuth2AuthorizedClientService clientService) {
        return new OktaAuthenticationFilter(clientService);
    }


服务应用程序.yml

spring:
  application:
    name: analytics-service

server:
  port: 8081

eureka:
  client:
    enabled: true

okta:
  oauth2:
    issuer: https://dev1234.okta.com/oauth2/default
    client-id: <value>
    client-secret: <value>

服务配置文件

@Configuration
    static class OktaOAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .authorizeRequests().anyRequest().authenticated()
                    .and()
                    .oauth2ResourceServer().jwt();
            // @formatter:on
        }
    }

    @Bean
    protected RestTemplate restTemplate() {
        return new OAuth2RestTemplate(oAuthDetails());
    }

摇篮文件

buildscript {
    dependencies {
        classpath('gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0')
    }
}

plugins {
    id 'org.springframework.boot' version '2.3.7.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.palantir.docker'

group = 'com.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    developmentOnly
    runtimeClasspath {
        extendsFrom developmentOnly
    }
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
}

ext {
    set('springCloudVersion', "Hoxton.SR9")
    set('springCloudServicesVersion', "2.3.0.RELEASE")
}

dependencies {
    implementation 'io.pivotal.spring.cloud:spring-cloud-services-starter-config-client'
    implementation 'io.pivotal.spring.cloud:spring-cloud-services-starter-service-registry'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'com.okta.spring:okta-spring-boot-starter:1.4.0'
    compileOnly    'org.projectlombok:lombok'
    implementation    'com.googlecode.json-simple:json-simple:1.1.1'
    annotationProcessor 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
    testImplementation 'org.mockito:mockito-core:2.7.22'
}

dependencyManagement {
    imports {
        mavenBom "io.pivotal.spring.cloud:spring-cloud-services-dependencies:${springCloudServicesVersion}"
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

task unpack(type: Copy) {
    dependsOn bootJar
    from(zipTree(tasks.bootJar.outputs.files.singleFile))
    into("build/dependency")
}
docker {
    name "${project.group}/${bootJar.baseName}"
    copySpec.from(tasks.unpack.outputs).into("dependency")
    buildArgs(['DEPENDENCY': "dependency"])
}

task standardTests(type: Test) {
    useJUnitPlatform {
    }
}  

更新 看起来范围“offline_access”确实有所作为。现在我收到 CORS 错误。过滤器到位后,我应该看不到这个吗?这是由于授权标头的存在吗?此外,如果我手动刷新浏览器,则会提供一个新令牌。那么没有CORS问题

zone.js:3243 POST http://localhost:8080/api/system/summary/salesHierarchy 401
core.js:15724 ERROR 
HttpErrorResponse {headers: HttpHeaders, status: 401, statusText: "OK", url: "http://localhost:8080/api/system/summary/salesHierarchy", ok: false, …}
:8080/verification:1 Access to XMLHttpRequest at 'https://dev-770454.okta.com/oauth2/default/v1/authorize?response_type=code&…0/login/oauth2/code/okta&nonce=4aoYCPl3OKhsOTTpCUiqayYjQXdpZLuonn6_Q6193-o' (redirected from 'http://localhost:8080/verification') from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
zone.js:3243 GET https://dev-770454.okta.com/oauth2/default/v1/authorize?response_type=code&…0/login/oauth2/code/okta&nonce=4aoYCPl3OKhsOTTpCUiqayYjQXdpZLuonn6_Q6193-o net::ERR_FAILED
core.js:15724 ERROR 
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://localhost:8080/verification", ok: false, …}

Update1 当 JWT 令牌过期时,我看到下面的错误,这是预期的。

2021-01-31 10:38:53 [http-nio-8080-exec-9] DEBUG o.s.s.o.s.r.w.BearerTokenAuthenticationFilter - Authentication request for failed!
org.springframework.security.oauth2.server.resource.InvalidBearerTokenException: An error occurred while attempting to decode the Jwt: Jwt expired at 2021-01-31T16:35:39Z

401 被发送到 UI 并且 UI 捕获它并重定向到 APP 中的另一个 url。这些是网关日志

2021-01-31 10:38:53 [http-nio-8080-exec-10] DEBUG o.s.s.w.s.HttpSessionRequestCache - DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/verification]
2021-01-31 10:38:53 [http-nio-8080-exec-10] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Calling Authentication entry point.
org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: A55D113FD46A0031CA1FADD21C008382; Granted Authorities: ROLE_ANONYMOUS
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@4180b4a8, returned: -1
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /oauth2/authorization/okta at position 1 of 17 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /oauth2/authorization/okta at position 2 of 17 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@422bdd20. A new one will be created.
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /oauth2/authorization/okta at position 3 of 17 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /oauth2/authorization/okta at position 4 of 17 in additional filter chain; firing Filter: 'CorsFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
    at 
......

o.s.s.w.a.ExceptionTranslationFilter - Calling Authentication entry point.
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Trying to match using AndRequestMatcher [requestMatchers=[NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@6f86a06a, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using org.springframework.security.web.csrf.CsrfFilter$DefaultRequiresCsrfMatcher@3f60847a
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Did not match
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.NegatedRequestMatcher - matches = true
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /oauth2/authorization/okta at position 6 of 17 in additional filter chain; firing Filter: 'LogoutFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@6f86a06a, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /oauth2/authorization/okta' doesn't match 'POST /logout'
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /oauth2/authorization/okta at position 7 of 17 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth2/authorization/okta'; against '/oauth2/authorization/{registrationId}'
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth2/authorization/okta'; against '/oauth2/authorization/{registrationId}'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - httpRequestMediaTypes=[image/avif, image/webp, image/apng, image/svg+xml, image/*, */*;q=0.8]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - Processing image/avif
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - application/xhtml+xml .isCompatibleWith image/avif = false
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - image/* .isCompatibleWith image/avif = true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - All requestMatchers returned true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Match found! Executing org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint@1c10eb3a
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Trying to match using AndRequestMatcher [requestMatchers=[NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], NegatedRequestMatcher [requestMatcher=AndRequestMatcher [requestMatchers=[OrRequestMatcher [requestMatchers=[Ant [pattern='/login'], Ant [pattern='/favicon.ico']]], AndRequestMatcher [requestMatchers=[NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@6f86a06a, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]]]]]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.NegatedRequestMatcher - matches = true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using NegatedRequestMatcher [requestMatcher=AndRequestMatcher [requestMatchers=[OrRequestMatcher [requestMatchers=[Ant [pattern='/login'], Ant [pattern='/favicon.ico']]], AndRequestMatcher [requestMatchers=[NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@6f86a06a, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]]]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using OrRequestMatcher [requestMatchers=[Ant [pattern='/login'], Ant [pattern='/favicon.ico']]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/login']
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/favicon.ico'; against '/login'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/favicon.ico']
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/favicon.ico'; against '/favicon.ico'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.OrRequestMatcher - matched
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using AndRequestMatcher [requestMatchers=[NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@6f86a06a, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.NegatedRequestMatcher - matches = true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@6f86a06a, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - httpRequestMediaTypes=[image/avif, image/webp, image/apng, image/svg+xml, image/*, */*;q=0.8]
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'https://dev-770454.okta.com/oauth2/default/v1/authorize?response_type=code&client_id=0oa2amci5xaQcrWbF357&scope=openid%20profile%20email%20address%20phone%20offline_access&state=yXMfdZoYPFl3yoISRnJLftlFnXmf3AnBgnUdGk0MBAc%3D&redirect_uri=http://localhost:8080/login/oauth2/code/okta&nonce=sKf92sk_wHRT6Zq1XwEw-NdYwik-CRMgXLZa_3jfKpA'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - Processing image/avif
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - application/xhtml+xml .isCompatibleWith image/avif = false
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@61505c39
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.MediaTypeRequestMatcher - image/* .isCompatibleWith image/avif = true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - All requestMatchers returned true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - All requestMatchers returned true
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.m.NegatedRequestMatcher - matches = false
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Did not match
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - No match found. Using default entry point org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@693f1240
2021-01-31 10:38:53 [http-nio-8080-exec-1] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'http://localhost:8080/login'
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@61505c39
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2021-01-31 10:38:53 [http-nio-8080-exec-8] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 1 of 17 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 2 of 17 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@422bdd20. A new one will be created.
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 3 of 17 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 4 of 17 in additional filter chain; firing Filter: 'CorsFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] TRACE o.s.c.n.zuul.web.ZuulHandlerMapping - Mapped to HandlerExecutionChain with [org.springframework.cloud.netflix.zuul.web.ZuulController@3ce8f88f] and 1 interceptors
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 5 of 17 in additional filter chain; firing Filter: 'CsrfFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Trying to match using org.springframework.security.web.csrf.CsrfFilter$DefaultRequiresCsrfMatcher@3f60847a
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.u.matcher.AndRequestMatcher - Did not match
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 6 of 17 in additional filter chain; firing Filter: 'LogoutFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /login' doesn't match 'POST /logout'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 7 of 17 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login'; against '/oauth2/authorization/{registrationId}'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 8 of 17 in additional filter chain; firing Filter: 'OAuth2LoginAuthenticationFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login'; against '/login/oauth2/code/*'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 9 of 17 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2021-01-31 10:38:53 [http-nio-8080-exec-6] DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@61505c39

在浏览器控制台上,我看到了错误

Access to XMLHttpRequest at 'https://dev-770454.okta.com/oauth2/default/v1/authorize?response_type=code&client_id=0oa2amci5xaQcrWbF357&scope=openid%20profile%20email%20address%20phone%20offline_access&state=yXMfdZoYPFl3yoISRnJLftlFnXmf3AnBgnUdGk0MBAc%3D&redirect_uri=http://localhost:8080/login/oauth2/code/okta&nonce=sKf92sk_wHRT6Zq1XwEw-NdYwik-CRMgXLZa_3jfKpA' (redirected from 'http://localhost:8080/verification') from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

网关上定义的过滤器是否应该不处理此 CORS 错误,或者是否未应用 CORS 过滤器?让我感到困惑的是,如果我转到浏览器并单击刷新按钮,它就可以正常工作。

4

2 回答 2

2

来自Spring Security 的文档

OAuth2RefreshToken 可以选择在授权码和密码授权类型的访问令牌响应中返回。如果OAuth2AuthorizedClient.getRefreshToken()可用且OAuth2AuthorizedClient.getAccessToken()已过期,它将由 自动刷新RefreshTokenOAuth2AuthorizedClientProvider

检查 Okta 应用程序中的刷新令牌框不足以获取刷新令牌。您还需要传入一个offline_access范围,否则它不会被返回。

我建议您升级到 Okta Spring Boot starter 2.0.0 并使用以下范围属性:

okta.oauth2.scopes=openid, email, profile, offline_access
于 2021-01-25T22:05:39.140 回答
0

如果您有刷新令牌,您可以将其发送到 /token 端点以获取新的访问令牌。您只想决定是抢先获取新令牌(基于它何时到期)还是重新获取(如果现有令牌停止工作,则请求新的访问令牌)。

于 2021-01-22T21:18:28.093 回答