我们计划使用密钥斗篷来保护一堆Web应用程序,其中一些是用Java编写的,有些是用JavaScript(带有React)的。
用户通过keycloak登录后,每个Web应用程序都需要检索已登录的用户以及该用户具有的领域/客户端角色。
(request -> KeycloakSecurityContext -> getIdToken -> getPreferredUsername/getOtherClaims)
。他们似乎工作正常对于JavaScript应用程序,我们尝试了以下代码,但无法成功将Keycloak初始化(请注意,此操作在Web应用程序代码中,已通过keycloak对用户进行了身份验证,该应用程序仅尝试检索使用以下身份登录的用户什么角色):
var kc = Keycloak({
url: 'https://135.112.123.194:8666/auth',
realm: 'oneRealm',
clientId: 'main'
});
//this does not work as it can't find the keycloak.json file under WEB-INF
//var kc = Keycloak('./keycloak.json');
kc.init().success(function () {
console.log("kc.idToken.preferred_username: " + kc.idToken.preferred_username);
alert(JSON.stringify(kc.tokenParsed));
var authenticatedUser = kc.idTokenParsed.name;
console.log(authenticatedUser);
}).error(function () {
window.location.reload();
});
我认为网络应用需要检索当前用户信息是很普遍的。谁知道上面的代码为什么不起作用?
谢谢。
您的代码要求Keycloak客户端库进行初始化,但不执行用户登录或检查用户是否已登录。
请参阅手册以获取详细信息:http://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter
您可能想做什么:
将check-sso添加到init以检查用户是否已登录并检索凭证keycloak.init({ onLoad: 'check-sso' ... })
。您甚至可以使用需要登录的信息。
请确保您为前端注册了单独的客户端。 Java后端客户端的类型为机密(或仅承载),而JavaScript客户端的类型为public。
您在这里找到一个非常小的示例:https://github.com/ahus1/keycloak-dropwizard-integration/blob/master/keycloak-dropwizard-bearer/src/main/resources/assets/ajax/app.js
或者,您可以注册一个回叫onAuthSuccess
,以在检索到用户信息后得到通知。
一旦在前端使用Keycloak,您将很快想在后端调用REST资源时查找承载令牌。
<script src="http://localhost:8080/auth/js/keycloak.js" type="text/javascript"></script>
<script type="text/javascript">
const keycloak = Keycloak({
"realm": "yourRealm",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "yourRealm/keep it default",
"public-client": true,
"confidential-port": 0,
"url": 'http://localhost:8080/auth',
"clientId": 'yourClientId',
"enable-cors": true
});
const loadData = () => {
console.log(keycloak.subject);
if (keycloak.idToken) {
document.location.href = "?user="+keycloak.idTokenParsed.preferred_username;
console.log('IDToken');
console.log(keycloak.idTokenParsed.preferred_username);
console.log(keycloak.idTokenParsed.email);
console.log(keycloak.idTokenParsed.name);
console.log(keycloak.idTokenParsed.given_name);
console.log(keycloak.idTokenParsed.family_name);
} else {
keycloak.loadUserProfile(function() {
console.log('Account Service');
console.log(keycloak.profile.username);
console.log(keycloak.profile.email);
console.log(keycloak.profile.firstName + ' ' + keycloak.profile.lastName);
console.log(keycloak.profile.firstName);
console.log(keycloak.profile.lastName);
}, function() {
console.log('Failed to retrieve user details. Please enable claims or account role');
});
}
};
const loadFailure = () => {
console.log('Failed to load data. Check console log');
};
const reloadData = () => {
keycloak.updateToken(10)
.success(loadData)
.error(() => {
console.log('Failed to load data. User is logged out.');
});
}
keycloak.init({ onLoad: 'login-required' }).success(reloadData);
</script>
简单的javascript客户端身份验证,没有框架。对于仍在寻找的人...
您现在可能已经解决了问题。我希望这个答案能帮助其他有麻烦的人。
使用JavaScript Adopter]时下面的javascript应该添加到html页面中。
<script src="http://localhost:8080/auth/js/keycloak.js"></script> <script> /* If the keycloak.json file is in a different location you can specify it: Try adding file to application first, if you fail try the another method mentioned below. Both works perfectly. var keycloak = Keycloak('http://localhost:8080/myapp/keycloak.json'); */ /* Else you can declare constructor manually */ var keycloak = Keycloak({ url: 'http://localhost:8080/auth', realm: 'Internal_Projects', clientId: 'payments' }); keycloak.init({ onLoad: 'login-required' }).then(function(authenticated) { alert(authenticated ? 'authenticated' : 'not authenticated'); }).catch(function() { alert('failed to initialize'); }); function logout() { // keycloak.logout('http://auth-server/auth/realms/Internal_Projects/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri') //alert("Logged Out"); } </script>
[https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter参考链接。
Note:
阅读有关添加json凭据的2种方法的注释。