微软的AD登录loginRedirect

news2024/11/18 10:45:15

 我这边技术栈是react+ts 如果你是vue,直接将tsx文件改成jsx就可以或者不该也没问题

 上篇文章介绍了msal 的弹框登录,先介绍下重定向登录这个相对弹框登录要烦很多。。。中国内网看我查询的资料很少,只有微软系的公司才会有相对应的需求。此处自己研究了2天并实现了功能现分享给大家。

思路我们实现重定向登录。顾名思义就是我先在msal服务登录成功,并成功通过msal api拿到登陆后信息accounts,isAuthenticated。根据accounts获取令牌(token),再将令牌与我们自己后端api去认证改用户是否可以登录此系统(欧莱雅一个公司几万人不是所有的人都可以登录所以加了这个接口认证)。重定向登录一定要组件化并要包裹layout 否者无法实现,这点给弹框登录的最大区别。

点击按钮代码以及调用登录方法handleLogin('redirect');就不做解释了,这个很简单

1、环境配置文件相关参数全局新建 authConfig.js

/*
 * 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、layouts文件

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、给layout 文件同级新建AADLogin.tsx

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;

 

 

 

登录成功。。。

国内资料很少。如有疑问请留言。推荐用梯子去查资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第二天|977.有序数组的平方 |209.长度最小的子数组 |59.螺旋矩阵II

977 有序数组平方 看完题后的思路 双指针 思路 本题如果使用暴力解法,需要按照绝对值将数组排序0(logn),然后进行平方.(或先平方,再排序,这样可以直接调用排序函数) 可以使用双指针法,定义两个指针,左指针是当前绝对值最小的负数,右指针是当前绝对值最小的整数,每一轮将较小…

03、openscenegraph(简称osg)源代码编译

通过上一节&#xff0c;我们准备下载好了osg源代码和依赖库&#xff0c;并安装了CMake、VS2013开发环境&#xff0c;接下来就可以进入编译工作了。 首先&#xff0c;将下载的openscenegraph源代码和依赖库3rdParty_VS2012.3_v110_x86_x64_V8b_full解压到同一个目录下&#xff…

构建系列之新一代利器Esbuild(下)

前言 本篇文章接上文&#xff0c;通过尝试使用esbuild的能力和业界的落地方案作为切入点继续深入esbuild的原理。 尝试Esbuild ESBuild在API层面上非常简洁, 主要的API只有两个: Transform和Build, 这两个API可以通过CLI, JavaScript, Go的方式调用 Transform主要用于对源代…

致而立之年的自己

&#xff08;点击即可收听&#xff09;时间是连续性的,人越长大,越能体会到,所谓的跨年与过年,其实是没有多大意义的但只要是人,就需要制造一些仪式感,弄出一些特殊的节日,用于安慰自己,对于逝去的曾今做一个告别,制造些记忆点然而,记忆这东西,是很容易健忘的,就像昨天,前天,吃…

泰克新2系示波器在微电网测试上的应用

直流微电网是由直流构成的微电网&#xff0c;是未来智能配用电系统的重要组成部分&#xff0c;对推进节能减排和实现能源可持续发展具有重要意义。相比交流微电网&#xff0c;直流微电网可更高效可靠地接纳风、直流逆变等分布式可再生能源发电系统、储能单元、电动汽车及其他直…

【C语言进阶】一万字教你实现简易通讯录管理

目录一. 通讯录要实现的功能1.项目文件分配2.通讯录基本功能二.test.c的实现1.逻辑代码的实现2.通讯录联系人信息的创建三.contacts.c的实现1.初始化通讯录2.添加联系人信息3.显示通讯录信息3.删除指定联系人信息4.查找指定联系人5.修改指定联系人信息6.以名字年龄排序通讯录7.…

进程收尾,初识线程

PCB中的信息:常见属性(有关于进程调度) 1)PID:(进程id)是进程中的身份标识&#xff0c;一个机器同一时刻&#xff0c;不可能有两个进程的PID相同&#xff0c;同一个系统的身份标识&#xff0c;进程的身份证号 2)一组内存指针&#xff1a;指名了该进程持有的一些重要数据和要执行…

一文讲解Linux虚拟化KVM-Qemu分析之virtio初探

说明&#xff1a; KVM版本&#xff1a;5.9.1QEMU版本&#xff1a;5.0.0工具&#xff1a;Source Insight 3.5&#xff0c; Visio 概述 从本文开始将研究一下virtio&#xff1b;本文会从一个网卡虚拟化的例子来引入virtio&#xff0c;并从大体架构上进行介绍&#xff0c;有个宏…

惊奇地发现:「精通或熟练使用 Navicat 」成为了业内企业招聘的任职要求之一

2023 年疫情逐渐消散&#xff0c;招聘市场也火热了起来。我们在招聘平台惊奇地发现&#xff1a;许多岗位招聘启事&#xff08;如&#xff1a;前端开发工程师、业务系统开发工程师和高级数据分析师等&#xff09;中提到&#xff0c;具备熟练使用 Navicat 软件成为任职要求之一。…

正版授权|bigmp4 Ai人工智能视频无损放大

bigmp4&#xff0c;使用先进人工智能 AI 模型&#xff0c;能将视频无损高清放大、增强画质、智能补帧使画面丝滑流畅栩栩如生同时支持黑白视频上色和慢动作。 人工智能视频无损放大 使用今年先进人工智能 AI 模型&#xff0c;能将视频无损高清放大、增强画质、智能补帧使画面丝…

Android Volley 基本使用

Android Volley 基本使用 本篇主要介绍 Google 给Android 平台提供的 Volley 一个 Http请求库 , 齐射! 1.概述 Volley是Google 提供的一个小巧的异步请求库,扩展很强支持okhttp,(默认是 Android2.3 及以上基于 HttpURLConnection&#xff0c;2.3 以下基于 HttpClient 实现), V…

<<数据结构>>向上调整建堆和向下调整建堆的分析(特殊情况,时间复杂度分析,两种建堆方法对比,动图)

今天&#xff0c;我来讲讲建堆算法中使用向上调整和向下调整。 目录建堆的应用向上调整建堆向下调整建堆向下调整建堆和向上调整建堆的选择建堆的应用 在数据结构模拟堆中&#xff0c;我们可能会通过输入数组的元素来进行建堆或者在堆排序中&#xff0c;我们也需要建堆&#x…

Kubernetes之网络排查详细文

文章目录前言一、Pod 网络异常1.1 网络异常大概分为如下几类&#xff1a;1.2 那么整个 Pod 网络异常分类可以如下图所示&#xff1a;二、常用网络排查工具2.1 tcpdump2.1.1 抓取示例2.1.2 选项分组2.1.3 过滤 TCP 标记位2.1.4 查找 http 包2.1.5 查找 DNS 流量2.1.6 查找对应流…

财务数字化在企业数字化转型中起到什么作用?

财务数字化在企业数字化转型中起到什么作用&#xff1f;许多企业在推动各大业务部门进行数字化转型时&#xff0c;往往会忽略财务部门。然而&#xff0c;作为掌握公司核心资源与数据和推动企业数字化建设的部门&#xff0c;财务也应成为企业数字化转型的重要突破口。 这篇就用…

Unity 之 Addressable可寻址系统 -- 可寻址系统使用介绍 -- 入门(三)

可寻址系统设置面板使用介绍介绍 -- 入门&#xff08;三&#xff09;一&#xff0c;可寻址系统目录介绍二&#xff0c;可寻址系统面板介绍2.1 Groups - 资源组2.2 Settings - 设置2.3 Profiles - 配置文件2.4 Event Viewer - 事件查看器2.5 Analyze - 分析工具2.6 Hosting - 托…

sklearn GridSearchCV网格搜索和SVM的两个参数 C 和 gamma

GridSearchCV&#xff0c;它存在的意义就是自动调参&#xff0c;只要把参数输进去&#xff0c;就能给出最优化的结果和参数。GridSearchCV用于系统地遍历多种参数组合&#xff0c;通过交叉验证确定最佳效果参数。 引用自&#xff1a;公众号&#xff1a; 写bug的程旭源 个人博客…

学生信息管理系统【JDBC+JS+MYSQL+HTML+JSP+Servlet】(一)

第一次发综合项目&#xff0c;无论是前端还是后端&#xff0c;都应用到了&#xff0c;项目写的很完整&#xff0c;我将分为四篇文章把项目代码写完&#xff0c;多多支持 一&#xff1a;项目背景 学生成绩管理系统是基于互联网的信息管理平台&#xff0c;主要提供成绩录入和查…

黄金的几种征兆

有别于股票、基金等的投资品种&#xff0c;由于现货黄金采用保证金的交易制度&#xff0c;因而使投资者有爆仓的可能。具体而言&#xff0c;爆仓是指在某些特殊条件下&#xff0c;投资者保证金账户中的客户权益变为负值的情形。在黄金交易的实战中&#xff0c;客户爆仓大多与资…

一文搞懂Spring,堪称Spring源码终结者

Spring的影响力想必无需与大家多说&#xff0c;如果你用spring&#xff0c;那么读读源码有助于对你最重要的工具的理解&#xff0c;好的框架源码也可以帮助我们理解什么是好代码。 刚参加工作那会&#xff0c;没想过去读源码&#xff0c;更没想过去改框架的源码&#xff1b;甚…

反序列化渗透与攻防(一)之PHP反序列化漏洞

前言 序列化和反序列化几乎是工程师们每天都要面对的事情&#xff0c;但是要精确掌握这两个概念并不容易&#xff1a;一方面&#xff0c;它们往往作为框架的一部分出现而湮没在框架之中&#xff1b;另一方面&#xff0c;它们会以其他更容易理解的概念出现&#xff0c;例如加密、…