Oauth 2.0 用OAuth2分离JHipster中的前端和API服务器不起作用
我用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客户端应用程序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.
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/'`
}
}),