IDM trust Keycloak
生活随笔
收集整理的這篇文章主要介紹了
IDM trust Keycloak
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
- 前言
- 一、實現(xiàn)原理
- 二、使用步驟
- 1.Enable Keycloak SSO
- 2.Trust keycloak's token in IDM
- 3.Get IDM's token
- 總結(jié)
?
前言
由于項目原因,需要啟用Keycloak做SSO,但是項目中又使用IDM管制訪問權(quán)限,我使用的方法如下。
?
一、實現(xiàn)原理
1.用戶登錄時,先通過Keycloak的登錄頁;
2.登錄通過后,拿Keycloak token換取IDM的信任,并獲得IDM token。
?
二、使用步驟
1.Enable Keycloak SSO
1.1?Reference?keycloak.js library?
<script src="keycloak.js"></script>1.2 Add?keycloak.init method? ??
var initOptions = {// responseMode: 'fragment',// flow: 'standard'url: 'https://keycloak-prd.xxx.com/auth',realm: 'xxx',clientId: 'xxx'};var keycloak = Keycloak(initOptions);keycloak.init({onLoad: 'login-required'}).success(function (authenticated) {//alert(authenticated ? 'authenticated' : 'not authenticated');if (!authenticated) {alert('not authenticated');} else {keycloak.loadUserProfile().success(data => {console.info(data);})}console.info(keycloak);}).error(function () {alert('failed to initialize');});function loadProfile() {keycloak.loadUserProfile().success(function(profile) {output(profile);}).error(function() {output('Failed to load profile');});}1.3 After the above settings, the system will be redirected to your keycloak's login page.?
?
2.Trust keycloak's token in IDM
代碼如下(示例):
/// <summary>/// Login with Keycloak/// </summary>[HttpGet]public async Task<IActionResult> LoginWithKeycloak(string returnUrl, string keyCloakToken){if (string.IsNullOrEmpty(returnUrl)){return Redirect("~/");}if (string.IsNullOrEmpty(keyCloakToken)){returnUrl = returnUrl + (returnUrl.IndexOf('?') > 0 ? "&" : "?") + "errmsg=No Keycloak token";return Redirect(returnUrl);}bool logged = false;string errmsg = string.Empty;try{var jsonPayload = Base64UrlEncoder.Decode(keyCloakToken.Split('.')[1]);JObject claims = (JObject)JsonConvert.DeserializeObject(jsonPayload);string keyCloakUrl = claims["iss"].ToString() + "/account";//從工廠獲取請求對象var client = _httpClientFactory.CreateClient();var request = new HttpRequestMessage(){Method = HttpMethod.Get,RequestUri = new Uri(keyCloakUrl),Content = new StringContent(string.Empty)};request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", keyCloakToken);var response = await client.SendAsync(request);if (response.IsSuccessStatusCode){var responseContent = response.Content.ReadAsStringAsync().Result;JObject user = (JObject)JsonConvert.DeserializeObject(responseContent);/*{ "username": "", "firstName": "", "lastName": "", "email": "", "emailVerified": false, "attributes": { "LDAP_ENTRY_DN": ["" ], "modifyTimestamp": [""], "createTimestamp": [""], "LDAP_ID": [""] }}*/AuthenticationProperties props = null;// issue authentication cookie with subject ID and usernamevar isuser = new IdentityServerUser(user["username"].ToString().ToUpper()){DisplayName = user["firstName"].ToString()};await HttpContext.SignInAsync(isuser, props);logged = true;}}catch (Exception ex){errmsg = ex.Message;}returnUrl = returnUrl + (returnUrl.IndexOf('?') > 0 ? "&" : "?") + ("step=IdmLogin") + (logged ? "" : ("&errmsg=" + errmsg));return Redirect(returnUrl);}?
3.Get IDM's token
代碼如下(示例):
index2.html?
<html> <head><script src="keycloak.js"></script> <script src="oidc-client.min.js"></script></head> <body><div><button onclick="keycloak.login()">Login</button><button onclick="keycloak.login({ action: 'UPDATE_PASSWORD' })">Update Password</button><button onclick="keycloak.logout()">Logout</button><button onclick="keycloak.register()">Register</button><button onclick="keycloak.accountManagement()">Account</button><button onclick="refreshToken(9999)">Refresh Token</button><button onclick="refreshToken(30)">Refresh Token (if <30s validity)</button><button onclick="loadProfile()">Get Profile</button><button onclick="updateProfile()">Update profile</button><button onclick="loadUserInfo()">Get User Info</button><button onclick="output(keycloak.tokenParsed)">Show Token</button><button onclick="output(keycloak.refreshTokenParsed)">Show Refresh Token</button><button onclick="output(keycloak.idTokenParsed)">Show ID Token</button><button onclick="showExpires()">Show Expires</button><button onclick="output(keycloak)">Show Details</button><button onclick="output(keycloak.createLoginUrl())">Show Login URL</button><button onclick="output(keycloak.createLogoutUrl())">Show Logout URL</button><button onclick="output(keycloak.createRegisterUrl())">Show Register URL</button><button onclick="output(keycloak.createAccountUrl())">Show Account URL</button></div><h5>Result of Keycloak</h5> <pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px; word-wrap: break-word; height:100px; overflow: scroll;" id="output"></pre><h5>Events of Keycloak</h5> <pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px; word-wrap: break-word; height:50px; overflow: scroll;" id="events"></pre><div><button onclick="renewIdmToken()">Refresh Token</button> </div><h5>Result of IDM</h5> <pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px; word-wrap: break-word; height:100px; overflow: scroll;" id="outputidm"></pre><h5>Events of IDM</h5> <pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px; word-wrap: break-word; height:50px; overflow: scroll;" id="eventsidm"></pre><script></script> <script src="idm-config.js"></script> <script src="keycloak-config.js"></script></body> </html>idm-config.js
?let initIdmOptions = {authority: "https://xx.xxx.com/auth", client_id: "peoplex", redirect_uri: "https://xx.xxx.com/keycloak/idm-callback.html",response_type: "id_token token",scope: "openid profile api1",post_logout_redirect_uri: "https://xx.xxx.com/keycloak/index2.html",// silent renew will get a new access_token via an iframe // just prior to the old access_token expiring (60 seconds prior)silent_redirect_uri: "https://xx.xxx.com/keycloak/idm-silent.html",automaticSilentRenew: true,}var oidcMgr = new Oidc.UserManager(initIdmOptions);function loginWithIdentityServer4(token){var url = initIdmOptions.authority + '/Account/LoginWithKeycloak?returnUrl={0}&keyCloakToken={1}';url = url.replace('{0}',window.location.href).replace('{1}',token);window.location.replace(url);}function idmLogin() {oidcMgr.signinRedirect();}function idmLogout() {oidcMgr.signoutRedirect();}function idmRedirectCallback(){new Oidc.UserManager().signinRedirectCallback().then(function (user) {console.log(user);window.history.replaceState({},window.document.title,window.location.origin + window.location.pathname);window.location = "index2.html?step=Completed";});}function IdmSilentCallback(){oidcMgr.signinSilentCallback();}function getIdmToken() {oidcMgr.getUser().then(function (user) {if (user) {console.log(user);outputIdm(user);} else {console.log("Not logged in");outputIdm("Not logged in");}});}function renewIdmToken() {oidcMgr.signinSilent().then(function () {console.log("silent renew success");}).catch(function (err) {console.log("silent renew error", err);});}function outputIdm(data) {if (typeof data === 'object') {data = JSON.stringify(data, null, ' ');}document.getElementById('outputidm').innerHTML = data;}function eventIdm(event) {var e = document.getElementById('eventsidm').innerHTML;document.getElementById('eventsidm').innerHTML = new Date().toLocaleString() + "\t" + event + "\n" + e;}oidcMgr.events.addUserLoaded(function (user) {//console.log("User loaded");eventIdm("User loaded");getIdmToken();});oidcMgr.events.addUserUnloaded(function () {//console.log("User logged out locally");eventIdm("User logged out locally");getIdmToken();});oidcMgr.events.addAccessTokenExpiring(function () {//console.log("Access token expiring..." + new Date());eventIdm("Access token expiring...");});oidcMgr.events.addSilentRenewError(function (err) {//console.log("Silent renew error: " + err.message);eventIdm("Silent renew error: " + err.message);});oidcMgr.events.addUserSignedOut(function () {//console.log("User signed out of OP");eventIdm("User signed out of OP");oidcMgr.removeUser();});?idm-callback.html?
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title></title><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Expires" content="0"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cache-control" content="no-cache"><meta http-equiv="Cache" content="no-cache"><script type="text/javascript" src="oidc-client.min.js"></script></head><body>Loading...<script src="idm-config.js"></script><script>idmRedirectCallback();</script></body></html>idm-silent.html?
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title></title><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Expires" content="0"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cache-control" content="no-cache"><meta http-equiv="Cache" content="no-cache"><script type="text/javascript" src="oidc-client.min.js"></script></head><body>Loading...<script src="idm-config.js"></script><script>IdmSilentCallback();</script> </body></html>keycloak-config.js?
let initOptions = {url: 'https://xx.xxx.com/auth',realm: 'k8sprdwzsi40',clientId: 'wigps',onLoad: 'login-required'}let keycloak = Keycloak(initOptions);keycloak.init({ onLoad: initOptions.onLoad }).then((auth) => {if (!auth) {alert('not authenticated');window.location.reload();return;} let errmsg = getQueryString('errmsg');if(errmsg){alert(getQueryString('errmsg'));return;}let step = getQueryString('step');if(!step){loginWithIdentityServer4(keycloak.token);return;}else{switch (step){case 'IdmLogin':idmLogin();break;case 'Completed':getIdmToken();loadProfile();break; default:break;} }//Token RefreshsetInterval(() => {refreshToken(70);}, 1000*60)}).catch(() => {alert("Authenticated Failed, ailed to initialize");});function getQueryString(name) {var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');var r = window.location.search.substr(1).match(reg);if (r != null) {return unescape(r[2]);}return null;}function loadProfile() {keycloak.loadUserProfile().then(function(profile) {output(profile);console.log(keycloak);}).catch(function() {output('Failed to load profile');});}function updateProfile() {var url = keycloak.createAccountUrl().split('?')[0];var req = new XMLHttpRequest();req.open('POST', url, true);req.setRequestHeader('Accept', 'application/json');req.setRequestHeader('Content-Type', 'application/json');req.setRequestHeader('Authorization', 'bearer ' + keycloak.token);req.onreadystatechange = function () {if (req.readyState == 4) {if (req.status == 200) {output('Success');} else {output('Failed');}}}req.send('{"email":"myemail@foo.bar","firstName":"test","lastName":"bar"}');}function loadUserInfo() {keycloak.loadUserInfo().then(function(userInfo) {output(userInfo);}).catch(function() {output('Failed to load user info');});}function refreshToken(minValidity) {keycloak.updateToken(minValidity).then(function(refreshed) {if (refreshed) {output(keycloak.tokenParsed);renewIdmToken();} else {output('Token not refreshed, valid for ' + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');}}).catch(function() {output('Failed to refresh token');});}function showExpires() {if (!keycloak.tokenParsed) {output("Not authenticated");return;}var o = 'Token Expires:\t\t' + new Date((keycloak.tokenParsed.exp + keycloak.timeSkew) * 1000).toLocaleString() + '\n';o += 'Token Expires in:\t' + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds\n';if (keycloak.refreshTokenParsed) {o += 'Refresh Token Expires:\t' + new Date((keycloak.refreshTokenParsed.exp + keycloak.timeSkew) * 1000).toLocaleString() + '\n';o += 'Refresh Expires in:\t' + Math.round(keycloak.refreshTokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds';}output(o);}function output(data) {if (typeof data === 'object') {data = JSON.stringify(data, null, ' ');}document.getElementById('output').innerHTML = data;}function event(event) {var e = document.getElementById('events').innerHTML;document.getElementById('events').innerHTML = new Date().toLocaleString() + "\t" + event + "\n" + e;}keycloak.onAuthSuccess = function () {event('Auth Success');};keycloak.onAuthError = function (errorData) {event("Auth Error: " + JSON.stringify(errorData) );};keycloak.onAuthRefreshSuccess = function () {event('Auth Refresh Success');};keycloak.onAuthRefreshError = function () {event('Auth Refresh Error');};keycloak.onAuthLogout = function () {event('Auth Logout');};keycloak.onTokenExpired = function () {event('Access token expired.');};keycloak.onActionUpdate = function (status) {switch (status) {case 'success':event('Action completed successfully'); break;case 'cancelled':event('Action cancelled by user'); break;case 'error':event('Action failed'); break;}};Please see the getIdmToken() method in the?idm-config.js for IDM's token。
總結(jié)
以上就是今天要講的內(nèi)容,本文僅僅簡單介紹了IDM和keycloak的使用,而IDM和keycloak提供了大量函數(shù)和方法。
?
? ??
?
? ??
?
總結(jié)
以上是生活随笔為你收集整理的IDM trust Keycloak的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mouse without border
- 下一篇: alm系统的使用流程_ALM用户使用手册