Enable public application OIDC client support
This change uses oidc-client-ts to enable dashy to authenticate with as OIDC client. It populates the groups and roles so that it can be used the same as keycloak for showing/hiding elements on the dashboard.
This commit is contained in:
@@ -3,6 +3,7 @@ import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
||||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
import { cookieKeys, localStorageKeys, userStateEnum } from '@/utils/defaults';
|
||||
import { isKeycloakEnabled } from '@/utils/KeycloakAuth';
|
||||
import { isOidcEnabled } from '@/utils/OidcAuth';
|
||||
|
||||
/* Uses config accumulator to get and return app config */
|
||||
const getAppConfig = () => {
|
||||
@@ -96,7 +97,7 @@ export const isAuthEnabled = () => {
|
||||
/* Returns true if guest access is enabled */
|
||||
export const isGuestAccessEnabled = () => {
|
||||
const appConfig = getAppConfig();
|
||||
if (appConfig.auth && typeof appConfig.auth === 'object' && !isKeycloakEnabled()) {
|
||||
if (appConfig.auth && typeof appConfig.auth === 'object' && !isKeycloakEnabled() && !isOidcEnabled()) {
|
||||
return appConfig.auth.enableGuestAccess || false;
|
||||
}
|
||||
return false;
|
||||
@@ -229,8 +230,10 @@ export const getUserState = () => {
|
||||
loggedIn,
|
||||
guestAccess,
|
||||
keycloakEnabled,
|
||||
oidcEnabled,
|
||||
} = userStateEnum; // Numeric enum options
|
||||
if (isKeycloakEnabled()) return keycloakEnabled; // Keycloak auth configured
|
||||
if (isOidcEnabled()) return oidcEnabled;
|
||||
if (!isAuthEnabled()) return notConfigured; // No auth enabled
|
||||
if (isLoggedIn()) return loggedIn; // User is logged in
|
||||
if (isGuestAccessEnabled()) return guestAccess; // Guest is viewing
|
||||
|
||||
@@ -541,6 +541,33 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"enableOidc": {
|
||||
"title": "Enable OIDC?",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "If set to true, enable OIDC. See appConfig.auth.oidc"
|
||||
},
|
||||
"oidc": {
|
||||
"type": "object",
|
||||
"description": "Configuration for OIDC",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"clientId",
|
||||
"endpoint"
|
||||
],
|
||||
"properties": {
|
||||
"endpoint": {
|
||||
"title": "OIDC Endpoint",
|
||||
"type": "string",
|
||||
"description": "Endpoint of OIDC provider"
|
||||
},
|
||||
"clientId": {
|
||||
"title": "OIDC Client Id",
|
||||
"type": "string",
|
||||
"description": "ClientId from OIDC provider"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enableHeaderAuth": {
|
||||
"title": "Enable HeaderAuth?",
|
||||
"type": "boolean",
|
||||
|
||||
90
src/utils/OidcAuth.js
Normal file
90
src/utils/OidcAuth.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import { UserManager, WebStorageStateStore } from 'oidc-client-ts';
|
||||
import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
||||
import { localStorageKeys } from '@/utils/defaults';
|
||||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
import { statusMsg, statusErrorMsg } from '@/utils/CoolConsole';
|
||||
|
||||
const getAppConfig = () => {
|
||||
const Accumulator = new ConfigAccumulator();
|
||||
const config = Accumulator.config();
|
||||
return config.appConfig || {};
|
||||
};
|
||||
|
||||
class OidcAuth {
|
||||
constructor() {
|
||||
const { auth } = getAppConfig();
|
||||
const { clientId, endpoint } = auth.oidc;
|
||||
const settings = {
|
||||
userStore: new WebStorageStateStore({ store: window.localStorage }),
|
||||
authority: endpoint,
|
||||
client_id: clientId,
|
||||
redirect_uri: `${window.location.origin}`,
|
||||
response_type: 'code',
|
||||
scope: 'openid profile email roles groups',
|
||||
response_mode: 'query',
|
||||
filterProtocolClaims: true,
|
||||
};
|
||||
|
||||
this.userManager = new UserManager(settings);
|
||||
}
|
||||
|
||||
async login() {
|
||||
const url = new URL(window.location.href);
|
||||
const code = url.searchParams.get('code');
|
||||
|
||||
if (code) {
|
||||
await this.userManager.signinCallback(window.location.href);
|
||||
window.location.href = '/';
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await this.userManager.getUser();
|
||||
|
||||
if (user === null) {
|
||||
await this.userManager.signinRedirect();
|
||||
} else {
|
||||
const { roles, groups } = user.profile;
|
||||
const info = {
|
||||
groups,
|
||||
roles,
|
||||
};
|
||||
|
||||
statusMsg(`user: ${user.profile.preferred_username}`, JSON.stringify(info));
|
||||
|
||||
localStorage.setItem(localStorageKeys.KEYCLOAK_INFO, JSON.stringify(info));
|
||||
localStorage.setItem(localStorageKeys.USERNAME, user.profile.preferred_username);
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
localStorage.removeItem(localStorageKeys.USERNAME);
|
||||
localStorage.removeItem(localStorageKeys.KEYCLOAK_INFO);
|
||||
|
||||
try {
|
||||
await this.userManager.signoutRedirect();
|
||||
} catch (reason) {
|
||||
statusErrorMsg('logout', 'could not log out. Redirecting to OIDC instead', reason);
|
||||
window.location.href = this.userManager.settings.authority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const isOidcEnabled = () => {
|
||||
const { auth } = getAppConfig();
|
||||
if (!auth) return false;
|
||||
return auth.enableOidc || false;
|
||||
};
|
||||
|
||||
let oidc;
|
||||
|
||||
export const initOidcAuth = () => {
|
||||
oidc = new OidcAuth();
|
||||
return oidc.login();
|
||||
};
|
||||
|
||||
export const getOidcAuth = () => {
|
||||
if (!oidc) {
|
||||
ErrorHandler("OIDC not initialized, can't get instance of class");
|
||||
}
|
||||
return oidc;
|
||||
};
|
||||
@@ -305,6 +305,7 @@ module.exports = {
|
||||
guestAccess: 2,
|
||||
notLoggedIn: 3,
|
||||
keycloakEnabled: 4,
|
||||
oidcEnabled: 5,
|
||||
},
|
||||
/* Progressive Web App settings, used by Vue Config */
|
||||
pwa: {
|
||||
|
||||
Reference in New Issue
Block a user