umi3.5 Inicio de sesión de Microsoft AD loginRedirect

 Mi pila de tecnología aquí es react+ts Si eres vue, puedes cambiar directamente el archivo tsx a jsx o no.

 El artículo anterior introdujo el inicio de sesión emergente de msal y primero introdujo el inicio de sesión de redirección, que es mucho más problemático que el inicio de sesión emergente. . . Según la Intranet de China, hay muy poca información que consulté, y solo las empresas con sede en Microsoft tienen las necesidades correspondientes. Aquí he investigado durante 2 días y me di cuenta de la función y ahora la comparto con todos.

Ideas Implementamos el inicio de sesión de redirección. Como su nombre lo indica, primero inicié sesión con éxito en el servicio msal y obtuve con éxito las cuentas de información de inicio de sesión, está autenticado a través de la API de msal. Obtenga el token (token) de acuerdo con las cuentas y luego use el token con nuestra propia API de back-end para autenticar si el usuario puede iniciar sesión en este sistema (L'Oreal tiene decenas de miles de personas, no todas pueden iniciar sesión , por lo que se agrega esta autenticación de interfaz). El inicio de sesión de redirección debe estar dividido en componentes y envuelto en un diseño, de lo contrario, no se puede realizar Esta es la mayor diferencia para el inicio de sesión emergente.

Haga clic en el código del botón y llame al método de inicio de sesión handleLogin('redirect'); no lo explicaré, esto es muy simple

1. Cree globalmente authConfig.js para los parámetros relevantes del archivo de configuración del entorno

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

import { LogLevel } from '@azure/msal-browser';

/**
 * Configuration object to be passed to MSAL instance on creation.
 * For a full list of MSAL.js configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
 */
export const msalConfig = {
  auth: {
    clientId: '277e3d78-7012-4c89-8e32-', // 公司在msal客户端编号 ,给微信小程序的id 一样
    authority:
      'https://login.microsoftonline.com/e4e1abd9-eac7-4a71-ab52-', //由应用程序的身份提供者实例和登录受众组成,可能还有租户 ID
    redirectUri: process.env.REDIRECT_URL, // 重定向的地址就是自己前端发布的访问地址,比如dev环境 http://localhost:8002
    tenantId: 'e4e1abd9-eac7-4a71-ab52-',
    scope: 'api://277e3d78-7012-4c89-8e32-/default',
    postLogoutRedirectUri: 'https://pto-test.lindemobile.cn/#/logout',
    navigateToLoginRequestUrl: false,
  },
  cache: {
    cacheLocation: 'localStorage', // This configures where your cache will be stored
    storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
  },
  system: {
    loggerOptions: {
      loggerCallback: (level, message, containsPii) => {
        if (containsPii) {
          return;
        }
        switch (level) {
          case LogLevel.Error:
            console.error(message);
            return;
          case LogLevel.Info:
            console.info(message);
            return;
          case LogLevel.Verbose:
            console.debug(message);
            return;
          case LogLevel.Warning:
            console.warn(message);
            return;
          default:
            return;
        }
      },
    },
  },
};

/**
 * Scopes you add here will be prompted for user consent during sign-in.
 * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
 * For more information about OIDC scopes, visit:
 * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
 */
export const loginRequest = {
  scopes: [msalConfig?.auth.scope],
};

/**
 * Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md
 */
export const graphConfig = {
  graphMeEndpoint: 'Enter_the_Graph_Endpoint_Herev1.0/me', //e.g. https://graph.microsoft.com/v1.0/me
};
export const tokenRequest = {
  scopes: [msalConfig?.auth.scope],
  forceRefresh: false, // Set this to "true" to skip a cached token and go to the server to get a new token
};

2. archivo de diseños

import { theme } from '@/app/config/theme';
import useAuthService, { AuthService } from '@/modules/User/useAuthService';
import useFilesService from '@/modules/File/useFileService';
import useFormatLanguageService, {
  FormatLanguageService,
} from '@/tools/formatLanguage';
import { UseRequestProvider } from 'ahooks';
import 'antd/dist/antd.less';
import axios from 'axios';
import React, { useState } from 'react';
import { createGlobalStyle, ThemeProvider } from 'styled-components';
import { IRouteComponentProps } from 'umi';
import './layouts.less';
import bg from '@/assets/images/bg.jpg';
import heardBG from '@/assets/images/heardBG.png';
import background from '../../public/images/background.jpg';
import { getToken } from '@/uitls/auth';
import GetAuth from './AADLogin';

export default function Layout({
  children,
  location,
  route,
  history,
  match,
}: IRouteComponentProps) {
  const [loginSuccess, setLoginSuccess] = useState(false);
  const formatLanguageService = useFormatLanguageService();
  const fileService = useFilesService();
  let token = getToken();
  const authService = useAuthService({
    mode: token ? '' : 'normal',
    formatLanguageService,
    defaultRoute: '/login',
    token,
  });
  return (
    // 注入主题样
    <ThemeProvider theme={theme}>
      <GetAuth //必须作为父盒子
        onLoginSuccess={() => setLoginSuccess(true)}
        loginSuccess={loginSuccess}
      >
        <UseRequestProvider
          value={
   
   {
            requestMethod: (param) =>
              axios(param).then((r) => {
                return r.data;
              }),
          }}
        >
          {children}
        </UseRequestProvider>
      </GetAuth>
    </ThemeProvider>
  );
}

3. Cree un nuevo AADLogin.tsx para el archivo de diseño en el mismo nivel

import React, { useState } from 'react';
import { useEffect } from 'react';

import {
  InteractionStatus,
  PublicClientApplication,
} from '@azure/msal-browser';
import { useIsAuthenticated, useMsal, MsalProvider } from '@azure/msal-react';

import { message } from 'antd';
import { history } from 'umi';
import { loginRequest, msalConfig } from '@/authConfig';
import Loading from '@/components/Loading';
import { GetUserInfo, ThirdLogin } from '@/app/request/requestApi';
import { setMenus, setRefershToken, setToken } from '@/uitls/auth';

export interface LoginProps {
  onLoginSuccess?: () => void;
  loginSuccess?: boolean;
  children?: any;
}
// 一定要放在最外层
//下面的所有组件MsalProvider都可以通过上下文访问PublicClientApplication实例,以及@azure/msal-react.
const msalInstance = new PublicClientApplication(msalConfig);

function GetAuthSub(props: LoginProps) {
  console.log(props, '--------');
  const [loading, setLoading] = useState<boolean>(false);
  const { instance: msalObject, accounts, inProgress } = useMsal();
  const isAuthenticated = useIsAuthenticated(); //判断用户是否通过身份验证
  useEffect(() => {
    msalInstance
      .handleRedirectPromise()
      .then((s) => {
        console.log(s);
        if (s !== null && s.account != null)
          //        currentAccount.setCurrentAccount(s.account.username, s.account.homeAccountId, s.account.tenantId);
          console.log('success');
      })
      .catch((a: any) => {
        console.log('err');
        console.log(a);
      });
  }, []);
  useEffect(() => {
    if (sessionStorage.getItem('loginType') !== 'Gool') {
      props.onLoginSuccess();
      console.log(accounts, inProgress, isAuthenticated, '--------');
      if (inProgress === InteractionStatus.Logout) {
        return;
      }
      //登录 如果要初始化就调用Az登录放开此处
      if (inProgress === InteractionStatus.None && !isAuthenticated) {
        // msalInstance.loginRedirect(loginRequest);
      }
      if (
        inProgress === InteractionStatus.None &&
        accounts.length > 0 &&
        isAuthenticated &&
        !sessionStorage.getItem('ADToken')
      ) {
        const curAccount = msalInstance.getActiveAccount() || accounts[0];
        const tokenRequest = {
          account: curAccount,
          scopes: [...loginRequest.scopes],
        };
        //获取访问令牌 token
        msalInstance.acquireTokenSilent(tokenRequest).then((response) => {
          sessionStorage.setItem('ADToken', response?.accessToken);
          // 调用自己后端认证msal token
          onThirdLogin(response?.accessToken);
        });
      }
    }
    //accounts登录信息  isAuthenticated是否授权
  }, [accounts, isAuthenticated, inProgress]);

  return <>{props.children}</>;
}
// 获取token
const onThirdLogin = (accessToken) => {
  Loading.show();
  const params = {
    accessToken,
    type: 7,
    code: 'code',
    clientType: 0,
  };
  ThirdLogin(params)
    .then((res) => {
      if (res.success) {
        message.success('Login succeeded');
        sessionStorage.setItem('loginType', 'AD');
        setToken(res.data.accessToken);
        setRefershToken(res.data.refreshToken);
        Loading.hide();
        onGetUserInfo('/LOREAL/allItems/items');
      } else {
        Loading.hide();
        message.error(res.msg);
        history.replace('/');
      }
    })
    .catch((err) => {
      Loading.hide();
      message.error(err.msg);
    });
};
// 用户信息
const onGetUserInfo = (homeRoute) => {
  GetUserInfo({}).then((res) => {
    if (res.success) {
      setMenus(JSON.stringify(res.data.menus));
      sessionStorage.setItem('realName', res.data.account.realName);
      sessionStorage.setItem('roles', res.data.account.roles[0]);
      history.replace(homeRoute);
    } else {
      message.error(res?.msg);
    }
  });
};
// 登录
export const handleLogin = (loginType) => {
  if (loginType === 'popup') {
    //弹框登录
    msalInstance.loginPopup(loginRequest).catch((e) => {
      console.log(e);
    });
  } else if (loginType === 'redirect') {
    //重定向登录
    msalInstance.loginRedirect(loginRequest);
  }
};
// 登出
export const signOut = () => {
  const logoutRequest = {
    postLogoutRedirectUri: msalConfig.auth.redirectUri,
    mainWindowRedirectUri: msalConfig.auth.redirectUri,
  };
  msalInstance.logoutRedirect(logoutRequest);
};
// 组件化 MsalProvider 获取msal授权流
const GetAuth = (props: LoginProps) => {
  return (
    <MsalProvider instance={msalInstance}>
      <GetAuthSub
        onLoginSuccess={props.onLoginSuccess}
        loginSuccess={props.loginSuccess}
      >
        {props.loginSuccess ? props.children : null}
      </GetAuthSub>
    </MsalProvider>
  );
};
export default GetAuth;

 

 

Inicio de sesión correcto. . .

La información interna es escasa. Por favor, deje un mensaje si tiene alguna pregunta. Se recomienda utilizar una escalera para comprobar la información.

Ventana emergente de inicio de sesión de Microsoft AD

Supongo que te gusta

Origin blog.csdn.net/weixin_46600931/article/details/128673073
Recomendado
Clasificación