I Have integrated keycloak with an angular app. Basically, both frontend and backend are on different server.Backend app is running on apache tomcat 8. Frontend app is running on JBoss welcome content folder.
Angular config
angular.element(document).ready(function ($http) {
var keycloakAuth = new Keycloak('keycloak.json');
auth.loggedIn = false;
keycloakAuth.init({ onLoad: 'login-required' }).success(function () {
keycloakAuth.loadUserInfo().success(function (userInfo) {
console.log(userInfo);
});
auth.loggedIn = true;
auth.authz = keycloakAuth;
auth.logoutUrl = keycloakAuth.authServerUrl + "/realms/app1/protocol/openid-connect/logout?redirect_uri=http://35.154.214.8/hrms-keycloak/index.html";
module.factory('Auth', function() {
return auth;
});
angular.bootstrap(document, ["themesApp"]);
}).error(function () {
window.location.reload();
});
});
module.factory('authInterceptor', function($q, Auth) {
return {
request: function (config) {
var deferred = $q.defer();
if (Auth.authz.token) {
Auth.authz.updateToken(5).success(function() {
config.headers = config.headers || {};
config.headers.Authorization = 'Bearer ' + Auth.authz.token;
deferred.resolve(config);
}).error(function() {
deferred.reject('Failed to refresh token');
});
}
return deferred.promise;
}
};
});
module.config(["$httpProvider", function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
}]);
Request Header
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:35.154.214.8:8080
Origin:http://35.154.214.8
Referer:http://35.154.214.8/accounts-keycloak/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Error on web console.
XMLHttpRequest cannot load http://35.154.214.8:8080/company/loadCurrencyList. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://35.154.214.8' is therefore not allowed access.
Cors filter on backend
@Component
public class CORSFilter implements Filter {
static Logger logger = LoggerFactory.getLogger(CORSFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
chain.doFilter(request, response);
}
public void destroy() {
}
}
I was fighting with KeyCloak and CORS and all of this for about two weeks, and this is my solution (for keycloak 3.2.1):
Its all about configuring KeyCloak server. It seems to be, that WebOrigin of your Realm needs to be
Only one origin "*".Thats all, what was needed for me.
If you enter your server as WebOrigin, the trouble begins. When you call keycloak.init in JavaScript, keycloak does not generate CORS headers, so you have to configure them manually, and as soon as you do so, and call keycloak.getUserInfo after successful init - you get double CORS headers, which is not allowed.
Somewhere deep inside of keycloak mailing lists is stated, that you need to set enable-cors=true in your keycloak.json, but there is nothing about that on keycloak.gitbooks.io. So it seems not to be true.
They also don't mention CORS when describing JavaScript and Node.Js adapters, and I don't know why, seems not to be important at all.
It also seems to be, that you should not touch WildFly configuration to provide CORS headers.
Besides, CORS in OIDC is a special KeyCloak feature (and not a bug).
Hopefully this answer serves you well.
You gave the answer to your own question, adding WebOrigin as * at client-level (NOT at Realm-level!), which worked for you, but in my own case it didn't. Actually, removing the * was the trick for me, because KC sent the CORS headers twice - removing it, stripped it to one time...
Thanks to your answer, I luckily found the answer on my problems...
What we all agree on is the KC documentation is at the least very poor.
It is written for dummies, but.... we are not dummies, neither the subject is...
It does not explain technical details. For instance, what are the responses from the endpoints. Searching the web (two weeks) does give a little - but why isn't it laid out in the documentation?
One example. But I have several...
Can we help with the documentation?
I had the same issue and (at least) for Keycloak Server Version 8.0.1 you can add a '+' as input of the 'Web Origins' field, which seems to be the best choice.
The '+' effect should be the same as adding (see screenshot below) 'http://localhost:4200' as 'Web Origins' entry.
This is what the 'Web Origins' field tooltip is saying:
"Allowed CORS origins. To permit all origins of "Valid Redirect URIs", add '+'. To permit all origins, add '*'." (see screenshot below)
Keycloak Client Web Origin Settings
The solution that worked for me was setting the Web Origins URL (Of my Client, not the Realm) from for example:
http://localhost:3000/
tohttp://localhost:3000
(Notice the lack of/
at the end). This way you are not opening it to all URLS by using*
.Faced this same problem working with Angular 6, Spring Boot for REST Web Services, and Keycloak.
Keycloak address: KEYCLOAK
Angular 6 App Address: ANGULAR_APP
Two REST WS secured with Keycloak and Spring Autoconfiguration: AA, BB
Flow was: Angular App request(GET) AA, AA request(GET) BB
Using XMLHttpRequest error was something like: Cannot load AA. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'ANGULAR_APP' is therefore not allowed access.
Using Observable from Angular it was: Failed to load AA: Redirect from 'BB' to 'KEYCLOAK' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'ANGULAR' is therefore not allowed access.
Tried with web origins: * to no solution
Never knew why Keycloak was doing that redirect that caused problem
Problem magically dissapeared when I switched security in service AA from Keycloak + Autoconfigure to Keycloak + Spring Security according to: https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/
Lost many days of sleep because of this. Just leaving this in case someone faces something similar.
I had the same problem and in my case it was caused by using an options object in keycloak js adapter creation, where the url to the auth server was falsely set to http instead of https:
but correct was