亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

后臺介紹:使用Keycloak進行OIDC認證

標簽:
架構 安全 API
使用Keycloak设置OIDC(开放身份验证)自定义身份提供程序的后台配置

Spotify的Backstage,一个开源平台,帮助开发者简化他们的软件基础设施,可以很好地与多种认证方式集成,包括OpenID Connect (OIDC)。本文将重点介绍如何让Backstage使用Keycloak,一个广泛使用的开源身份和访问管理解决方案(IAM),作为其OIDC提供商。

假设你对Backstage和Keycloak有所了解,让我们深入了解一下集成的细节。在这里、如果你需要,快速回顾一下为何及何时使用Backstage。

幕后:使用模板和Terraform进行基础设施自动化:Backstage模板和Terraform在基础设施自动化中的应用
整合

后台预设了多种身份验证提供程序,例如GitHub、Okta、OAuth2中继等。虽然设置这些默认解决方案相对简单,但与类似Keycloak的OIDC提供程序集成则需要更多的工作。以下基于原始文档并针对Keycloak进行了调整,简述步骤。我将插入一些注释来引导您设置。

⚠️ 注意: 请注意,这里提供的代码文件是完整的,虽然它们不仅仅包含更改。请检查每个文件顶部的文件名,因为它们对应于 Backstage 仓库 中的代码所在位置。

按照简单的步骤,您可以按照以下步骤启用提供程序:

  • 创建一个API参考文档以便识别提供商及其将处理身份验证的API工厂。
    // packages/app/src/apis.ts  
    import {  
      ScmIntegrationsApi,  
      scmIntegrationsApiRef,  
      ScmAuth,  
    } from '@backstage/integration-react';  
    import {  
      AnyApiFactory,  
      configApiRef,  
      createApiFactory,  
      ApiRef,  
      createApiRef,  
      OpenIdConnectApi,  
      ProfileInfoApi,  
      BackstageIdentityApi,  
      SessionApi,  
      discoveryApiRef,  
      oauthRequestApiRef  
    } from '@backstage/core-plugin-api';  
    import { OAuth2 } from '@backstage/core-app-api';  
    // `ProfileInfoApi & BackstageIdentityApi & SessionApi` 是登录所必需的
    export const oidcAuthApiRef: ApiRef<  
      OpenIdConnectApi & // 处理身份验证的 OICD API  
      ProfileInfoApi & // 从相关身份提供商请求用户信息资料的资料 API  
      BackstageIdentityApi & // 处理并关联用户资料与 Backstage 身份的 Backstage 身份 API。  
      SessionApi // 会话 API,处理用户登录后的会话。
    > = createApiRef({  
      id: 'auth.example.oidc', // 只要不与其他 Api ref ID 冲突就可以是任何东西  
    });  
    export const apis: AnyApiFactory[] = [  
      createApiFactory({  
        api: oidcAuthApiRef,  
        deps: {  
          discoveryApi: discoveryApiRef,  
          oauthRequestApi: oauthRequestApiRef,  
          configApi: configApiRef,  
        },  
        factory: ({ discoveryApi, oauthRequestApi, configApi }) =>  
          OAuth2.create({  
            discoveryApi,  
            oauthRequestApi,  
            provider: {  
              id: 'example',  
              title: '示例身份提供商',  
              icon: () => null,  
            },  
            environment: configApi.getOptionalString('auth.environment'),  
            defaultScopes: ['openid'],  
            popupOptions: {  
              size: {  
                fullscreen: true,  
                // 或指定弹出窗口的宽度和高度  
                //width: 1000,  
                //height: 1000,  
              },  
            },  
          }),  
      }),  
      createApiFactory(  
      {  
        api: scmIntegrationsApiRef,  
        deps: { configApi: configApiRef },  
        factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),  
      }),  
      ScmAuth.createDefaultApiFactory(),  
    ];

添加身份提供器以便你可以进行身份验证,并添加解析器来处理认证的结果。

    // packages/backend/src/plugins/auth.ts  
    import {  
      createRouter,  
      providers,  
      defaultAuthProviderFactories,  
    } from '@backstage/plugin-auth-backend';  
    import { Router } from 'express';  
    import { PluginEnvironment } from '../types';  

    import { DEFAULT_NAMESPACE, stringifyEntityRef } from '@backstage/catalog-model';  

    export default async function createPlugin(  
      env: PluginEnvironment,  
    ): Promise<Router> {  
      return await createRouter({  
        logger: env.logger,  
        config: env.config,  
        database: env.database,  
        discovery: env.discovery,  
        tokenManager: env.tokenManager,  
        providerFactories: {  
          ...defaultAuthProviderFactories,  

          // 注意:在这里添加提供程序和解析函数以从令牌中提取数据  
          example: providers.oidc.create({  
            signIn: {  
              resolver(info, ctx) {  
                const userRef = stringifyEntityRef({  
                  kind: 'User',  
                  name: info.result.userinfo.sub, // 注意:此信息来自令牌中的userinfo.sub字段  
                  namespace: DEFAULT_NAMESPACE,  
                });  
                return ctx.issueToken({  
                  claims: {  
                    sub: userRef, // 用户标识  
                    ent: [userRef], // 用户声明拥有的身份列表  
                  },  
                });  
              },  
            },  
          }),  
        },  
      });  
    }
  • 配置提供方以便能够访问您的第三方认证服务。

    # app-config.yaml  
    ...  
    auth:  
      ### 提供 auth.session.secret 将启用会话  
      session:  
        secret: supersecretcookie  
      # 参考 https://backstage.io/docs/auth/ 了解更多有关身份验证提供程序的详情  
      environment: development  
      providers:  
        example:  
          development:  
            # 注意:在此处提供 Keycloak 的 URL  
            metadataUrl: https://auth.example.com/auth/realms/master/.well-known/openid-configuration  
            clientId: backstage  
            clientSecret: supersecretsecret  
    ..
  • 在登录页面添加提供商,让用户可以用它登录。
    // packages/app/src/App.tsx  
    import React from 'react';  
    import { Navigate, Route } from 'react-router-dom';  
    import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';  
    import {  
      CatalogEntityPage,  
      CatalogIndexPage,  
      catalogPlugin,  
    } from '@backstage/plugin-catalog';  
    import {  
      CatalogImportPage,  
      catalogImportPlugin,  
    } from '@backstage/plugin-catalog-import';  
    import {  
      ScaffolderPage,  
      scaffolderPlugin,  
    } from '@backstage/plugin-scaffolder';  
    import { orgPlugin } from '@backstage/plugin-org';  
    import { SearchPage } from '@backstage/plugin-search';  
    import { TechRadarPage } from '@backstage/plugin-tech-radar';  
    import {  
      TechDocsIndexPage,  
      techdocsPlugin,  
      TechDocsReaderPage,  
    } from '@backstage/plugin-techdocs';  
    import { TechDocsAddons } from '@backstage/plugin-techdocs-react';  
    import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';  
    import { UserSettingsPage } from '@backstage/plugin-user-settings';  
    import { apis } from './apis';  
    import { entityPage } from './components/catalog/EntityPage';  
    import { searchPage } from './components/search/SearchPage';  
    import { Root } from './components/Root';  
    import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';  
    import { createApp } from '@backstage/app-defaults';  
    import { AppRouter, FlatRoutes } from '@backstage/core-app-api';  
    import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';  
    import { RequirePermission } from '@backstage/plugin-permission-react';  
    import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';  
    import { oidcAuthApiRef } from './apis';  
    import { SignInProviderConfig, SignInPage } from '@backstage/core-components';  

    // 注意:这里添加示例提供商以显示登录页面的示例  
    const keycloakProvider: SignInProviderConfig = { // 登录提供商配置  
      id: 'oidc-auth-provider',  
      title: 'Keycloak SSO',  
      message: '使用Keycloak SSO',  
      apiRef: oidcAuthApiRef,  
    };  
    const app = createApp({  
      components: {  
        SignInPage: props => (  
          <SignInPage  
            {...props}  
            auto  
            provider={keycloakProvider}  
          />  
        ),  
      },  
      apis,  
      bindRoutes({ bind }) {  
        // 绑定外部路由  
        bind(catalogPlugin.externalRoutes, {  
          createComponent: scaffolderPlugin.routes.root,  
          viewTechDoc: techdocsPlugin.routes.docRoot,  
          createFromTemplate: scaffolderPlugin.routes.selectedTemplate,  
        });  
        bind(apiDocsPlugin.externalRoutes, {  
          registerApi: catalogImportPlugin.routes.importPage,  
        });  
        bind(scaffolderPlugin.externalRoutes, {  
          registerComponent: catalogImportPlugin.routes.importPage,  
          viewTechDoc: techdocsPlugin.routes.docRoot,  
        });  
        bind(orgPlugin.externalRoutes, {  
          catalogIndex: catalogPlugin.routes.catalogIndex,  
        });  
      },  
    });  
    const routes = (  
      <FlatRoutes>  
        <Route path="/" element={<Navigate to="catalog" />} />  
        <Route path="/catalog" element={<CatalogIndexPage />} />  
        <Route  
          path="/catalog/:namespace/:kind/:name"  
          element={<CatalogEntityPage />}  
        >  
          {entityPage}  
        </Route>  
        <Route path="/docs" element={<TechDocsIndexPage />} />  
        <Route  
          path="/docs/:namespace/:kind/:name/*"  
          element={<TechDocsReaderPage />}  
        >  
          <TechDocsAddons>  
            <ReportIssue />  
          </TechDocsAddons>  
        </Route>  
        <Route path="/create" element={<ScaffolderPage />} />  
        <Route path="/api-docs" element={<ApiExplorerPage />} />  
        <Route  
          path="/tech-radar"  
          element={<TechRadarPage width={1500} height={800} />}  
        />  
        <Route  
          path="/catalog-import"  
          element={  
            <RequirePermission permission={catalogEntityCreatePermission}>  
              <CatalogImportPage />  
            </RequirePermission>  
          }  
        />  
        <Route path="/search" element={<SearchPage />}>  
          {searchPage}  
        </Route>  
        <Route path="/settings" element={<UserSettingsPage />} />  
        <Route path="/catalog-graph" element={<CatalogGraphPage />} />  
      </FlatRoutes>  
    );  
    // 导出默认应用根组件(包含所有路由和组件)  
    export default app.createRoot(  
      <>  
        <AlertDisplay />  
        <OAuthRequestDialog />  
        <AppRouter>  
          <Root>{routes}</Root>  
        </AppRouter>  
      </>,  
    );
因此,结尾

最后,将Keycloak作为OIDC提供者与Spotify的Backstage结合使用,为开发人员提供了一个坚实的框架,用于在其软件生态系统中管理用户的认证和授权。尽管Backstage从一开始就支持多种认证方式,但要让两者无缝对接则需要一些额外的步骤。这篇文章详细介绍了必要的步骤,使开发人员能够利用Keycloak强大的身份和访问管理工具,同时享受Backstage提供的高效开发体验。

想了解最新的云技术,快来订阅我的每周简报,Cloud Chirp,快来订阅吧!🚀

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
軟件工程師
手記
粉絲
47
獲贊與收藏
152

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消