使用OAuth2分离JHipster中的前端和API服务器不起作用 [英] Separating the front-end and the API server in JHipster with OAuth2 does not work
问题描述
我用OAuth2创建了一个简单的JHipster 6.2.0角度应用程序,我还单独生成了一个客户端应用程序。此外,我还使用keyloak.yml为Keyloak创建了一个停靠器 这是JHipster附带的,但为作为数据库的PostgreSQL提供了更多参数。
在同一上下文中运行两个应用程序,默认情况下,一切正常。
为了在不同的上下文中运行这两个应用程序,如https://www.jhipster.tech/separating-front-end-and-api/所述,我在客户端的webpack.Common.js中设置了SERVER_API_URL='http://localhost:8080'
。
在此场景中,在dev模式下:
- 我在IDE(IntelliJ)中启动后端应用程序
- 我执行NPM START启动客户端
- 在Chrome浏览器中,我调用http://localhost:9000
- 单击"登录"链接
- 使用管理员凭据填充密钥罩的登录窗口
在此场景中,我从未到达Account资源上的API/Account方法公共UserDTO getAccount(主体主体)。在Chrome Network选项卡中,我看到两个帐户呼叫,状态代码均为302 OK。
如有任何解决此问题的想法,我们将不胜感激。
cmd
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
.yo-rc.json前端
{
"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
}
}
.yo-rc.json后端
{
"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": []
}
}
应用程序的安全性.yml
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-dev.yml:
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
WebConfigurer.java中的CorsFilter:
@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);
}
SecurityConfiguration.java中的配置
@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
}
webpack.Common.js(客户端应用程序)
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/'`
}
}),
推荐答案
正如@MattRaible所说,问题是在这个角度客户机上没有真正了解OAuth的逻辑。因此,基本上,您应该遵循以下步骤来解决问题:
- 安装Keyloak节点模块并在angular.js、webpack.Common.js和index.html几个文件中将其激活
- 添加密钥罩服务以与密钥罩服务器交互
- 添加拦截器以将我们的授权令牌放在每个http请求上
- 稍作更改即可调整LogoutResource.java。
您可以在Github repo中找到此解决方案的示例。您还可以详细说明here。
这篇关于使用OAuth2分离JHipster中的前端和API服务器不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!