Issue
I am running an Angular application with a Spring Boot MVC API in combination with Keycloak. I configured Angular following the instruction found under https://www.npmjs.com/package/keycloak-angular and it generally works fine.
In my Angular components I use the img
tag to include Images, which are served by my Spring Boot application
<img *ngIf="id" src="api/v1/profile/image/{{id}}">
The MVC endpoint looks like this :
@GetMapping(value = "profile/image/{id}")
public @ResponseBody byte[] getProfileImage(@AuthenticationPrincipal Jwt jwt, @PathVariable String id)
throws IOException {
...
}
The problem is that I receive a 401 Response Code on the first load of the image.
Here are my key findings:
- The load of the image does (never) contain the "authorization: bearer
..." request header (as opposed to requests, that are sent via the
HttpClient
) - The first failing request will have a
set-cookie
response Header - Consecutive Requests will contain the cookie as part of the Request Header and will work
Can anybody point out, what I can do? Can keycloak be configured in a way, that the load of Images will contain the bearer authetication header?
Solution
<img *ngIf="id" src="api/v1/profile/image/{{id}}">
This kind of image is loaded by the browser and not by HttpClient
. And HttpClient
is already configured to inject Authorization
header in your case, not the browser so that is a root cause of the issue.
You may load image content from the URL api/v1/profile/image/{{id}}
with HttpClient
and then do a inlining of that image content into HTML with base64 encoding:
<img src="data:<correct content type>;base64, <base 64 data of the image content>" />
e.g.:
<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" />
It is good solution for small images (this approach is used for social icons usually).
Or you can save authorization into cookie in the same format as your service provider is expecting before you create image). Then browser will send that authorization cookie in the each request. Of course there can be a problem with cross domain cookies.
Answered By - Jan Garaj