我已经在我的Spring启动应用程序中集成了keycloak适配器,如文档中所述。工作流程正在运行。 最初,我在属性中使用会话令牌存储,但我想摆脱它并且是无状态的。所以,我将选项更改为cookie令牌存储。
我可以看到我的Spring Boot应用程序确实在KEYCLOAK_ADAPTER_STATE cookie(screenshot)中发送了keycloak访问令牌。正如所料,它被标记为HTTP cookie。
但是,即使我在查询中打开withCredentials选项,当我查询后端时,进一步的角度http请求也不会发送该cookie。
let options : RequestOptions = new RequestOptions();
options.withCredentials = true;
this.http.get('myservice', options)
如何在无状态的http调用中使用该令牌?
非常感谢!
答案 0 :(得分:0)
使用Interceptors:
HTTP拦截是@ angular / common / http的主要功能。同 拦截,你声明检查和转换HTTP的拦截器 从您的应用程序到服务器的请求。同样的拦截器 也可以检查并转换服务器的响应 回到应用程序。多个拦截器形成一个 请求/响应处理程序的前后链
从'../ auth.service'导入{AuthService};
@Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private auth: AuthService) {} intercept(req: HttpRequest<any>, next: HttpHandler) { // Get the auth token from the service. const authToken = this.auth.getAuthorizationToken(); // Clone the request and replace the original headers with // cloned headers, updated with the authorization. const authReq = req.clone({ headers: req.headers.set('Authorization', authToken) }); // send cloned request with header to the next handler. return next.handle(authReq); } }
...
我认为您应该将
options.withCredentials = true;
设置为任何请求
import { Injectable } from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse, HttpErrorResponse} from '@angular/common/http';
import {Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/do';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = req.clone({
withCredentials: true
});
return next
.handle(req)
.do(event => {
if (event instanceof HttpResponse) {}
}, (error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.router.navigate(['/login']);
}
}
});
}
}
答案 1 :(得分:0)
我发现了问题。到达我的页面的初始请求URL是“/ app / mymodule”,因此keycloak HTTP令牌绑定到/ app路径;但我查询后端的JS http请求是“/ services / myservice”,因此浏览器不会发送cookie,因为根路径不匹配。我在/ app / services下移动了我的服务,现在令牌按预期发送,并经过适当验证:)。
答案 2 :(得分:0)
尝试使用https://www.npmjs.com/package/keycloak-angular。
有了出色的文档,它使该过程变得更加容易。
它使用npm软件包中内置的拦截器,因此您不必担心将令牌附加到每个请求。
答案 3 :(得分:0)
默认情况下,如angular-keycloak documentation HttpClient拦截器中所述,将为以下格式添加Authorization标头:从应用程序到服务器的所有HTTP请求的Authorization:Bearer TOKEN
。
您可以配置要从HTTPClient拦截器配置中添加带有密钥斗篷令牌的HTTP授权标头中要排除的请求URL。
可以在app-init.ts(请参阅angular-keycloak文档)中的keycloak初始化程序函数中配置HttpClient拦截器;
import { KeycloakService } from 'keycloak-angular';
export function initializer(keycloak: KeycloakService): () => Promise<any> {
return (): Promise<any> => keycloak.init({
config: {
url: 'http://localhost:8080/auth',
realm: 'your-realm',
clientId: 'client-id'
},
initOptions: {
onLoad: 'login-required',
checkLoginIframe: false
},
enableBearerInterceptor: true,
bearerPrefix: 'Bearer',
bearerExcludedUrls: [
'/assets',
'/clients/public']
});
}