Oauth 2.0 用OAuth2分离JHipster中的前端和API服务器不起作用

Oauth 2.0 用OAuth2分离JHipster中的前端和API服务器不起作用,oauth-2.0,jhipster,Oauth 2.0,Jhipster,我用OAuth2创建了一个简单的JHipster 6.2.0 Angular应用程序,还单独生成了一个客户端应用程序。此外,我还使用keydove.yml为keydove创建了一个docker 这是JHipster附带的,但PostgreSQL作为数据库还有一些参数 在同一上下文上运行两个应用程序,默认情况下,一切正常 为了在不同的上下文中运行这两个应用程序,正如在中所说的,我设置了SERVER\u API\u URL=http://localhost:8080'在webpack.common.

我用OAuth2创建了一个简单的JHipster 6.2.0 Angular应用程序,还单独生成了一个客户端应用程序。此外,我还使用keydove.yml为keydove创建了一个docker 这是JHipster附带的,但PostgreSQL作为数据库还有一些参数

在同一上下文上运行两个应用程序,默认情况下,一切正常

为了在不同的上下文中运行这两个应用程序,正如在中所说的,我设置了SERVER\u API\u URL=http://localhost:8080'在webpack.common.js的客户端

在此场景中,在开发模式下:

我在IDE IntelliJ中启动后端应用程序 我执行npm启动以启动客户机 在Chrome浏览器中,我调用 点击登录链接 用管理员凭据填充KeyClope的登录窗口 我没有收到一个文本为“You's logging as user admin.”的窗口,而是再次返回同一主页,并带有登录链接。因此,我无法完成登录过程

在这个场景中,我从未接触过AccountResource上的api/account、方法public userdt和getAccountPrincipal。在Chrome网络选项卡中,我看到两个呼叫account,两个呼叫状态代码均为302 Ok

如有任何解决此问题的想法,将不胜感激

旋度指令

.yo-rc.json前端

.yo-rc.json后端

application.yml中的安全性

应用程序中的CORS-dev.yml:

WebConfigure.java中的CorsFilter:

SecurityConfiguration.java中的配置

webpack.common.js客户端应用程序


JHipster中的OAuth2.0支持希望所有东西都打包在同一个应用程序中,并作为单个工件进行部署。这是因为它使用授权代码流,这是OAuth 2.0流中最安全的。它利用Spring安全性,所有访问令牌和ID令牌都存储在服务器上。建立了允许客户端与服务器对话的cookie

Angular或React/Vue客户端中没有真正了解OAuth的逻辑。事实上,代码看起来非常类似于会话身份验证


如果你真的想使用一个单独的客户端,我建议你使用创建你的角度客户端。JHipster将使用它,并在此场景中充当OAuth 2.0资源服务器。

JHipster中的OAuth 2.0支持希望所有内容都打包在同一个应用程序中,并作为单个工件进行部署。这是因为它使用授权代码流,这是OAuth 2.0流中最安全的。它利用Spring安全性,所有访问令牌和ID令牌都存储在服务器上。建立了允许客户端与服务器对话的cookie

Angular或React/Vue客户端中没有真正了解OAuth的逻辑。事实上,代码看起来非常类似于会话身份验证


如果你真的想使用一个单独的客户端,我建议你使用创建你的角度客户端。JHipster将使用它,并在这个场景中充当OAuth 2.0资源服务器。

正如@MattRaible所说,问题是Angular客户端中没有真正了解OAuth的逻辑。因此,基本上,您应该遵循以下步骤来解决问题:

安装KeyClope节点模块并在几个文件中激活它:angular.js、webpack.common.js和index.html 添加keydepot服务以与keydepot服务器交互 添加一个拦截器,将我们的授权令牌放在每个http请求上 对LogoutResource.java稍作修改。
您可以在此处找到此解决方案的示例。您也有一个详细的解释。

正如@MattRaible所说,问题是Angular客户机中没有真正了解OAuth的逻辑。因此,基本上,您应该遵循以下步骤来解决问题:

安装KeyClope节点模块并在几个文件中激活它:angular.js、webpack.common.js和index.html 添加keydepot服务以与keydepot服务器交互 添加一个拦截器,将我们的授权令牌放在每个http请求上 对LogoutResource.java稍作修改。
您可以在此处找到此解决方案的示例。您也有详细的解释。

非常感谢您的回答!我会尝试为杰普斯特离子。非常感谢你的回答!我会为杰普斯特试一试。
curl "http://localhost:8080/api/account" -H "Referer: http://localhost:9000/" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" --compressed
{
  "generator-jhipster": {
    "promptValues": {
      "nativeLanguage": "es"
    },
    "jhipsterVersion": "6.2.0",
    "applicationType": "monolith",
    "baseName": "clientlauncher",
    "useSass": true,
    "clientPackageManager": "npm",
    "clientFramework": "angularX",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "authenticationType": "oauth2",
    "cacheProvider": "no",
    "databaseType": "postgres",
    "devDatabaseType": "postgres",
    "prodDatabaseType": "postgres",
    "testFrameworks": [],
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [],
    "enableTranslation": true,
    "nativeLanguage": "es",
    "languages": ["es", "en"],
    "blueprints": [],
    "skipServer": true
  }
}

{
  "generator-jhipster": {
    "promptValues": {
      "packageName": "com.xxx.yyy",
      "nativeLanguage": "es"
    },
    "jhipsterVersion": "6.2.0",
    "applicationType": "monolith",
    "baseName": "smartoee",
    "packageName": "com.xxx.yyy",
    "packageFolder": "com/xxx/yyy",
    "serverPort": "8080",
    "authenticationType": "oauth2",
    "cacheProvider": "ehcache",
    "enableHibernateCache": true,
    "websocket": false,
    "databaseType": "sql",
    "devDatabaseType": "postgresql",
    "prodDatabaseType": "postgresql",
    "searchEngine": false,
    "messageBroker": false,
    "serviceDiscoveryType": false,
    "buildTool": "maven",
    "enableSwaggerCodegen": false,
    "useSass": true,
    "clientPackageManager": "npm",
    "clientFramework": "angularX",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "testFrameworks": [],
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [],
    "enableTranslation": true,
    "nativeLanguage": "es",
    "languages": ["es", "en"],
    "blueprints": []
  }
}

  security:
    oauth2:
      client:
        provider:
          oidc:
            issuer-uri: http://192.168.0.159:9080/auth/realms/jhipster
        registration:
          oidc:
            client-id: web_app
            client-secret: web_app

  cors:
    allowed-origins: '*'
    allowed-methods: '*'
    allowed-headers: '*'
    exposed-headers: 'Authorization,Link,X-Total-Count'
    allow-credentials: true
    max-age: 1800   

I also tried, but it didn't work:   
  cors:
    allowed-origins:
      - http://localhost:8080
      - http://localhost:9000
      - http://localhost:9060
      - http://127.0.0.1:8080
      - http://127.0.0.1:9000
      - http://127.0.0.1:9060
      - http://192.168.0.159:9080
    allowed-methods: '*'
    allowed-headers: '*'
    exposed-headers: 'Authorization,Link,X-Total-Count'
    allow-credentials: true
    max-age: 1800
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = jHipsterProperties.getCors();
        if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
            log.debug("Registering CORS filter");
            source.registerCorsConfiguration("/api/**", config);
            source.registerCorsConfiguration("/management/**", config);
            source.registerCorsConfiguration("/v2/api-docs", config);
        }
        return new CorsFilter(source);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .antMatchers("/app/**/*.{js,html}")
            .antMatchers("/i18n/**")
            .antMatchers("/content/**")
            .antMatchers("/swagger-ui/index.html")
            .antMatchers("/test/**");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
            .addFilterBefore(corsFilter, CsrfFilter.class)
            .exceptionHandling()
            .accessDeniedHandler(problemSupport)
        .and()
            .headers()
            .contentSecurityPolicy("default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com data:")
        .and()
            .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
        .and()
            .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
        .and()
            .frameOptions()
            .deny()
        .and()
            .authorizeRequests()
            .antMatchers("/api/auth-info").permitAll()
            .antMatchers("/api/**").authenticated()
            .antMatchers("/management/health").permitAll()
            .antMatchers("/management/info").permitAll()
            .antMatchers("/management/prometheus").permitAll()
            .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
        .and()
            .oauth2Login()
        .and()
            .oauth2ResourceServer()
                .jwt()
                .jwtAuthenticationConverter(jwtAuthorityExtractor)
                .and()
            .and()
                .oauth2Client();
        // @formatter:on
    }

       new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: `'${options.env}'`,
                BUILD_TIMESTAMP: `'${new Date().getTime()}'`,
                VERSION: `'${packageJson.version}'`,
                DEBUG_INFO_ENABLED: options.env === 'development',
                // The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`.
                // If this URL is left empty (""), then it will be relative to the current context.
                // If you use an API server, in `prod` mode, you will need to enable CORS
                // (see the `jhipster.cors` common JHipster property in the `application-*.yml` configurations)
                SERVER_API_URL: `'http://localhost:8080/'`
            }
        }),