【转】掀起Azure AD的盖头来——深入理解Microsoft Graph应用程序和服务权限声明

引子

这是一篇计划外的文章。我们都知道要进行Microsoft Graph的开发的话,需要进行应用程序注册。这个在此前我已经有专门的文章写过了。但这里存在一个小的问题:国内版的Office 365在申请好之后,并没有像国际版那样,有一个对应的可以注册和管理应用程序的Azure的界面。说起来有点绕,国际版的Office 365管理员可以直接登陆到portal.azure.com进行应用程序注册和管理,但国内版却不行。这个问题目前来说还是一个know issue。不过,在帮助一些客户解决这个问题的过程中,我们也有一些变通的做法,例如我下面的这篇文章就是摘自于世纪互联技术支持的标准做法。

国内版Office 365和Azure AAD绑定的问题及解决方案

上述方案中建议客户要另外在购买一个Azure AD的订阅,然后可以跟Office 365那个Tenant绑定起来。这个从一定程度上解决了问题,但不是那么完美。本文给大家分享的是我们另外研究出来的一些经验做法。

理解Office 365与Azure AD的关系

从逻辑上说,Azure是微软的智能云平台,在这个平台上,不光是运行了全球不计其数的客户的应用程序,也承载着包括Office 365在内的规模庞大的一些SaaS平台。而Office 365的用户管理和应用管理,本质上就是用Azure AD来实现的。当然,国外的版本,Azure AD还可以做到更多,包括组织配置文件、设备管理、按条件的访问控制等等。限于篇幅,本文不对这些高级功能进行展开,我们仅仅针对用户管理和应用管理,尤其是应用管理这块来一探究竟。

本文的例子,因为主要是要演示如何解决国内版的问题,所以截图全部采用国内版Office 365或者Azure 请注意,登陆国内版本的Azure,有两种方式,一种是传统门户(manage.windowsazure.cn),一种是新门户(portal.azure.cn)。新门户毫无疑问带来了一些新的功能,例如支持使用最新的Resource Management的方式创建和管理资源。但是,要进行Azure AD的操作的话,目前还只能在传统门户中进行

这就是我们喜闻乐见的Azure AD管理界面,用户管理不用多说了,这里可以增加和删除用户,修改用户的一些基本信息。我们重点关注的是应用管理的这个部分。

稍微简单地回顾一下相关的概念,注册应用程序(application)有两种不同类型(本机或者Web),除了提供一些基本信息(对于Web应用程序而言,关键一点在于提供ReplyUrl)之外,最重要的就是定义该应用程序需要访问的资源,以及申请的权限了。资源,在Azure AD内部的技术范畴来说,是较为ServicePrinciple的一个对象,而所谓的权限,又分为两种,一种是delegated permission,一种是application permission。前者也称为oauth权限,这是需要用户授权,并且模拟用户的身份去进行操作,适合于一些有用户交互的应用程序,而后者(也称为role权限)则适合于一些在后台运行的服务或者自动运行的脚本

必须承认,就算是有图形化界面,要完全理解上面这些东西也多少需要一定的时间。与此同时,如果我们连图形化界面都没有的话,怎么来创建应用程序并且为其申请相关资源的权限呢,这有点挑战,但是谢天谢地,我们还是找到了一些方法。

通过PowerShell来创建应用程序并且定义服务和权限声明

我旗帜鲜明地喜欢PowerShell,尤其是用来管理Azure AD以及Office 365的时候,它总是能让我们事半功倍。为了演示下面的功能,我需要提醒你准备如下的软件环境。

请在Windows 10的机器上面,安装如下的几个组件

  1. 下载安装官方提供的Microsoft Online Service Sign-in Assistant for IT Professionals https://go.microsoft.com/fwlink/p/?LinkId=286152
  2. 下载安装官方提供的Azure Active Directory Connection http://connect.microsoft.com/site1164/Downloads/DownloadDetails.aspx?DownloadID=59185
  3. 请在本地用管理员身份打开PowerShell,并运行命令 Install-Module -Name AzureAD

当然,你还得需要有一个Office 365 的管理员账号信息

为了验证你是否安装成功如上的组件,请重新打开一个PowerShell窗口,运行下面的命令

$credential = Get-Credential
# 此时会弹出一个登陆框,请输入Office 365管理员和密码信息,如果没有错误请继续Connect-AzureAD -Credential $credential -AzureEnvironmentName AzureChinaCloud
# 如果没有错误请继续
Get-AzureADApplication

查询所有的服务定义信息

我们需要通过脚本获取到当前这个Azure AD中已经定义好的服务信息

Get-AzureADServicePrincipal

正常情况下将返回下面的结果

ObjectIdAppIdDisplayName
06d6e7e4-dcb4-4783-a617-78d89bb584f30000000f-0000-0000-c000-000000000000Microsoft.Azure.GraphExplorer
0a80ca08-a6b5-42d9-91a3-1a93c6c25b0543e38210-29b3-411d-b9f7-4a75b5fd2786工作流
0f6b73aa-9a6d-4c25-b518-5aef795042d600000002-0000-0ff1-ce00-000000000000Office 365 Exchange Online
13fc1a89-6a58-406a-9cb2-42e92c458fd3aa9ecb1e-fd53-4aaa-a8fe-7a54de2c1334Office 365 Configure
1a17c404-11db-442b-93ae-e0751e1563b700000007-0000-0ff1-ce00-000000000000Microsoft.ExchangeOnlineProtection
224fdbf8-fbe8-4d54-b98e-f8b9ad15cac800000005-0000-0000-c000-000000000000Microsoft.Azure.Workflow
26df55ee-6a90-4a17-879c-1a982094512c00000009-0000-0000-c000-000000000000Power BI Service
2ab85e47-1ba1-4948-9a95-f16eef6215aa00000003-0000-0ff1-ce00-000000000000Office 365 SharePoint Online
30236da4-3a49-4615-bb09-d665e5938602181dc382-d034-45ad-b7d7-4f440986737bsample
30ee19e0-47bd-4a3d-8e2b-3752f02d4ffc2d4d3d8e-2be3-4bef-9f87-7875a61c29deOneNote
3319d71d-8dfc-42ff-8fa0-0aa64f55335000000003-0000-0000-c000-000000000000Microsoft Graph
348ecf66-4f9c-4ec5-8db4-c86171859ea5c5393580-f805-4401-95e8-94b7a6ef2fc2Office 365 Management APIs
465b5392-ee37-4d69-be91-dad28b5fb77a00000004-0000-0ff1-ce00-000000000000Office 365 Lync Online
465eec3f-9bcd-4c27-b071-780b86f010830000000c-0000-0000-c000-000000000000Microsoft.Azure.ActiveDirectoryUX
4ba6a93c-053e-4575-83aa-419fcc7cadb5c84c5f13-394f-4807-9a35-317cffa11143工作流
4fa14876-02c2-4089-a450-2b8b45d17ae000000002-0000-0000-c000-000000000000Windows Azure Active Directory
524c2aaa-6ca4-4db5-9876-b758bbd4d6c78d3a7d3c-c034-4f19-a2ef-8412952a9671MicrosoftOffice
6226889d-694d-4ee0-8717-0997c544b94eab27a73e-a3ba-4e43-8360-8bcc717114d8Microsoft.OfficeModernCalendar
63246e22-5673-4665-9744-e33f18aceaf3aa2cd2a1-5a04-4e64-b76a-0a0f21e9d1d9webappsample123
67749e7c-7d67-4338-abdd-82f13ff2201000000006-0000-0ff1-ce00-000000000000Microsoft.Office365Portal
6de0d20c-2b7f-4aed-803c-f3157018b59b00000013-0000-0000-c000-000000000000Windows Azure Management Portal
72f64ca3-d200-423b-92da-4f3dd6621ef91142d051-c271-4044-b1ac-522c8029e3b7websampletest
76c56681-2887-4cd4-a375-971669f0d4718fca0a66-c008-4564-a876-ab3ae0fd5cffMicrosoft.SMIT
778437c2-766d-4853-8738-2f397efeae060f698dd4-f011-4d23-a33e-b36416dcb1e6OfficeClientService
793601bf-1a81-400d-bb7d-68db352702c5ae675dd6-076c-4036-9d0b-f5a4e9c10c71nativeapplication
79a7fbfe-a0d5-4416-8c8f-6a523d45cd4c803ee9ca-3f7f-4824-bd6e-0b99d720c35cAzure Media Service
7f07985a-6657-41cb-b5f6-14c3554b027d326128ad-f5f4-474c-bb19-c5e9b7780ba0微软 Office 365 移动办公套件
866d1fbf-bf6d-4e30-a8ad-570317df9642797f4846-ba00-4fd7-ba43-dac1f8f63013Windows Azure Service Management API
8ac0becf-4180-43fd-883f-18bda7f458270f6edad5-48f2-4585-a609-d252b1c52770AIGraphClient
8f5f81a0-7690-4bad-b097-bb22a9940041168f7c69-e70d-4a14-ae22-c069b5d296bcwebapp
93a3c4d5-6451-4648-8195-b00eafe51b0ef05ff7c9-f75a-4acd-a3b5-f4b6a870245dSharePoint Android
94decd41-c70a-4255-b73a-0d52ead4dde92ab3d641-6164-4930-8f58-68d56787ab47testapplication
9c4b5e57-6ec2-4218-be29-70d197664262595d87a1-277b-4c0a-aa7f-44f8a068eafcMicrosoft.SupportTicketSubmission
a4c307c2-d229-4cea-a51c-c498b146fc3f601d4e27-7bb3-4dee-8199-90d47d527e1cMicrosoft.Office365.ChangeManagement
a534ad32-c4a0-491e-810f-7499a8b9016ac44b4083-3bb0-49c1-b47d-974e53cbdf3cIbiza Portal
a913c56c-7a86-479e-894e-9649f99f78418fad9a3d-ce06-4d85-8f9a-873164f0cafcnative
c259baa5-c050-420d-a4a9-3130dbeed2f96f82282e-0070-4e78-bc23-e6320c5fa7deMicrosoft.DiscoveryService
ce72c49b-a6df-45c6-9055-76d7eb684a9d3f56a5d5-7882-4290-9fd8-3908d734b3fedeamon
dc4e9fbc-9e1d-4900-9ea1-dfc9b8d414c50000000b-0000-0000-c000-000000000000Microsoft.SellerDashboard
e1d2b488-d085-4af5-bd97-d2436f72fd7de3583ad2-c781-4224-9b91-ad15a8179ba0Microsoft.ExtensibleRealUserMonitoring
ebf95d4c-7ccf-4ecf-ac48-793d2782f98d67e3df25-268a-4324-a550-0de1c7f97287Microsoft.OfficeWebAppsService
f0df0bc2-1c0a-446b-9eb6-7a4cf974907961a7b0d6-2bc9-48b6-8653-ef6b496815cbGraphExplorer

虽然列了这么多,但其实我们一般最关注就是下面这个服务 ObjectId | AppId | DisplayName -------- | ----- | ----------- 3319d71d-8dfc-42ff-8fa0-0aa64f553350 | 00000003-0000-0000-c000-000000000000 | Microsoft Graph

查询服务的权限信息

有了服务的基本信息,我们就可以查询它的详细信息,尤其是我们关注的权限定义这部分信息了

$graph = Get-AzureADServicePrincipal -ObjectId 3319d71d-8dfc-42ff-8fa0-0aa64f553350
# 这个命令将Microsoft Graph这个服务定义保存为一个变量$graph | fl * 
# 这个命令将显示详细信息

下面我将演示一下如何将它的两类权限分别列举出来

$graph.Oauth2Permissions 
# 这个会列举出来所有的用户模拟权限
IdIsEnabledTypeUserConsentDescriptionUserConsentDisplayNameValue
58e15261-dfce-4dbd-b1a9-6a513ccf39cdTrueUserAllows the app to read, update, create, and delete contacts you have permissions to access, including your own and shared contacts.Read and write to your and shared contactsContacts.ReadWrite.Shared
c8ee694a-ac5f-44eb-9487-f4fea3a6538dTrueUserAllows the app to read contacts you have permissions to access, including your own and shared contacts.Read your and shared contactsContacts.Read.Shared
9e044dd2-b119-478e-8b0c-3143ff864625TrueUserAllows the app to read, update, create and delete events in all calendars in your organization you have permissions to access. This includes delegate and shared calendars.Read and write to your and shared calendarsCalendars.ReadWrite.Shared
f1731364-f498-453c-a95f-c57fdbeff4f1TrueUserAllows the app to read events in all calendars that you can access, including delegate and shared calendars.Read calendars?you can accessCalendars.Read.Shared
2bf44396-38c4-4826-813f-75074b46a125TrueUserAllows the app to send mail as you or on-behalf of someone else.Send mail on behalf of others or yourselfMail.Send.Shared
0772b0b8-18f9-4412-a1dc-cdbb000727faTrueUserAllows the app to read, update, create, and delete mail you have permission to access, including your own and shared mail. Does not allow the app to send mail on your behalf.Read and write mail?you can accessMail.ReadWrite.Shared
07382180-f05b-4f94-8e51-02736bd78f14TrueUserAllows the app to read mail you can access, including shared mail.Read mail you can accessMail.Read.Shared
e1fe6dd8-ba31-4d61-89e7-88639da4683dTrueUserAllows you to sign in to the app with your organizational account and let the app read your profile. It also allows the app to read basic company information.Sign you in and read your profileUser.Read
b4e74841-8e56-480b-be8b-910348b18b4cTrueUserAllows the app to read your profile, and discover your group membership, reports and manager. It also allows the app to update your profile information on your behalf.Read and update your profileUser.ReadWrite
b340eb25-3456-403f-be2f-af7a0d370277TrueUserAllows the app to read a basic set of profile properties of other users in your organization on your behalf. Includes display name, first and last name, email address and photo.Read all users' basic profilesUser.ReadBasic.All
a154be20-db9c-4678-8ab7-66f6cc099a59TrueAdminAllows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.Read all users' full profilesUser.Read.All
204e0828-b5ca-4ad8-b9f3-f32a958e7cc4TrueAdminAllows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.Read and write all users' full profilesUser.ReadWrite.All
5f8c59db-677d-491f-a6b8-5f174b11ec1dTrueAdminAllows the app to list groups, and to read their properties and all group memberships on your behalf. Also allows the app to read calendar, conversations, files, and other group content for all groups you can access.Read all groupsGroup.Read.All
4e46008b-f24c-477d-8fff-7bb4ec7aafe0TrueAdminAllows the app to create groups and read all group properties and memberships on your behalf. Additionally allows the app to manage your groups and to update group content for groups you are a member of.Read and write all groupsGroup.ReadWrite.All
06da0dbc-49e2-44d2-8312-53f166ab848aTrueAdminAllows the app to read data in your organization's directory.Read directory dataDirectory.Read.All
c5366453-9fb0-48a5-a156-24f0c49a4b84TrueAdminAllows the app to read and write data in your organization's directory, such as other users, groups. It does not allow the app to delete users or groups, or reset user passwords.Read and write directory dataDirectory.ReadWrite.All
0e263e50-5827-48a4-b97c-d940288653c7TrueAdminAllows the app to have the same access to information in your work or school directory as you do.Access the directory as youDirectory.AccessAsUser.All
570282fd-fa5c-430d-a7fd-fc8dc98a9dcaTrueUserAllows the app to read email in your mailbox.Read your mailMail.Read
024d486e-b451-40bb-833d-3e66d98c5c73TrueUserAllows the app to read, update, create and delete email in your mailbox. Does not include permission to send mail.Read and write access to your mailMail.ReadWrite
e383f46e-2787-4529-855e-0e479a3ffac0TrueUserAllows the app to send mail as you.Send mail as youMail.Send
465a38f9-76ea-45b9-9f34-9e8b0d4b0b42TrueUserAllows the app to read events in your calendars.Read your calendarsCalendars.Read
1ec239c2-d7c9-4623-a91a-a9775856bb36TrueUserAllows the app to read, update, create and delete events in your calendars.Have full access to your calendarsCalendars.ReadWrite
ff74d97f-43af-4b68-9f2a-b77ee6968c5dTrueUserAllows the app to read contacts in your contact folders.Read your contactsContacts.Read
d56682ec-c09e-4743-aaf4-1a3aac4caa21TrueUserAllows the app to read, update, create and delete contacts in your contact folders.Have full access of your contactsContacts.ReadWrite
10465720-29dd-4523-a11a-6a75c743c9d9TrueUserAllows the app to read your files and files shared with you.Read your files and files shared with youFiles.Read
5c28f0bf-8a70-41f1-8ab2-9032436ddb65TrueUserAllows the app to read, create, update, and delete your files and files shared with you.Have full access to your files and files shared with youFiles.ReadWrite
8019c312-3263-48e6-825e-2b833497195bTrueUserAllows the app to read, create, update and delete files in the application's folder.Have full access to the application's folderFiles.ReadWrite.AppFolder
17dde5bd-8c17-420f-a486-969730c1b827TrueUserAllows the app to read and write files that you select. After you select a file, the app has access to the file for several hours.Read and write selected filesFiles.ReadWrite.Selected
5447fe39-cb82-4c1a-b977-520e67e724ebTrueUserAllows the app to read files that you select. After you select a file, the app has access to the file for several hours.Read selected filesFiles.Read.Selected
205e70e5-aba6-4c52-a976-6d2d46c48043TrueUserAllow the application to read documents and list items in all site collections on your behalfRead items in all site collectionsSites.Read.All
$graph.AppRoles
# 这个会列举出来所有的应用权限
DescriptionDisplayNameIdIsEnabledValue
Allows the app to read mail in all mailboxes without a signed-in user.Read mail in all mailboxes810c84a8-4a9e-49e6-bf7d-12d183f40d01TrueMail.Read
Allows the app to create, read, update, and delete mail in all mailboxes without a signed-in user. Does not include permission to send mail.Read and write mail in all mailboxese2a3a72e-5f79-4c64-b1b1-878b674786c9TrueMail.ReadWrite
Allows the app to send mail as any user without a signed-in user.Send mail as any userb633e1c5-b582-4048-a93e-9f11b44c7e96TrueMail.Send
Allows the app to read events of all calendars without a signed-in user.Read calendars in all mailboxes798ee544-9d2d-430c-a058-570e29e34338TrueCalendars.Read
Allows the app to create, read, update, and delete events of all calendars without a signed-in user.Read and write calendars in all mailboxesef54d2bf-783f-4e0f-bca1-3210c0444d99TrueCalendars.ReadWrite
Allows the app to read all contacts in all mailboxes without a signed-in user.Read contacts in all mailboxes089fe4d0-434a-44c5-8827-41ba8a0b17f5TrueContacts.Read
Allows the app to create, read, update, and delete all contacts in all mailboxes without a signed-in user.Read and write contacts in all mailboxes6918b873-d17a-4dc1-b314-35f528134491TrueContacts.ReadWrite
Allows the app to read group properties and memberships, and read the calendar and conversations for all groups, without a signed-in user.Read all groups5b567255-7703-4780-807c-7be8301ae99bTrueGroup.Read.All
Allows the app to create groups, read all group properties and memberships, update group properties and memberships, and delete groups. Also allows the app to read and write group calendar and conversations. All of these operations can be performed by the app without a signed-in user.Read and write all groups62a82d76-70ea-41e2-9197-370581804d09TrueGroup.ReadWrite.All
Allows the app to read data in your organization's directory, such as users, groups and apps, without a signed-in user.Read directory data7ab1d382-f21e-4acd-a863-ba3e13f7da61TrueDirectory.Read.All
Allows the app to read and write data in your organization's directory, such as users, and groups, without a signed-in user. Does not allow user or group deletion.Read and write directory data19dbc75e-c2e2-444c-a770-ec69d8559fc7TrueDirectory.ReadWrite.All
Allows the app to read and write all device properties without a signed in user. Does not allow device creation, device deletion or update of device alternative security identifiers.Read and write devices1138cb37-bd11-4084-a2b7-9f71582aeddbTrueDevice.ReadWrite.All
Allows the app to read user profiles without a signed in user.Read all users' full profilesdf021288-bdef-4463-88db-98f22de89214TrueUser.Read.All
Allows the app to read and update user profiles without a signed in user.Read and write all users' full profiles741f803b-c850-494e-b5df-cde7c675a1caTrueUser.ReadWrite.All

创建应用程序

创建应用程序的PowerShell命令是New-AzureADApplication,它的详细用法请参考这里 https://docs.microsoft.com/en-us/powershell/module/azuread/new-azureadapplication?view=azureadps-2.0

$app= New-AzureADApplication -DisplayName "yourapplicationname"  -ReplyUrls "https://websample.com/replyurl" -Homepage "https://websample.com" -IdentifierUris "https://websample.com"# 这是用来创建Web应用程序的$app= New-AzureADApplication -DisplayName "yourapplicationname"  -PublicClient $true# 这是用来创建本地应用程序的,设置PublicClient属性为true即可$app#请保存app的具体信息,尤其是AppId

创建密钥

如果上面创建的是Web 应用程序,还需要为应用程序创建密钥。这里会用到的PowerShell命令是New-AzureADApplicationPasswordCredential,它的详细用法请参考这里 https://docs.microsoft.com/en-us/powershell/module/azuread/new-azureadapplicationpasswordcredential?view=azureadps-2.0

New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId# 正常情况下,将返回一个为期一年的密钥信息CustomKeyIdentifier :
EndDate             : 7/12/2018 10:25:28 AM
KeyId               :
StartDate           : 7/12/2017 10:25:28 AM
Value               : /TD0rbE5gwm/a6TGqUhqVY46LA16rir6Zwm7pK69prI=# 请保存这个Value信息

绑定服务和设定权限

我们已经创建了应用程序,也为他申请了一个密钥,下面就是最后也是最关键的环节————为应用程序绑定服务并且设定权限了。下面这个代码段是为上面创建好的应用程序,并且为其申请了四个delegated permission。(具体这四个权限对应的是什么,请参考上面的表格)

$graphrequest = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"$graphrequest.ResourceAccess = New-Object -TypeName "System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]"$ids =@("024d486e-b451-40bb-833d-3e66d98c5c73","e383f46e-2787-4529-855e-0e479a3ffac0","e1fe6dd8-ba31-4d61-89e7-88639da4683d","b340eb25-3456-403f-be2f-af7a0d370277")foreach($id in $ids){$obj = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $id,"Scope"# 如果是AppRole权限,则第二个参数为Role$graphrequest.ResourceAccess.Add($obj)
}$graphrequest.ResourceAppId = "00000003-0000-0000-c000-000000000000"Set-AzureADApplication -ObjectId $app.ObjectId -RequiredResourceAccess ($graphrequest)
# 这句命令的RequiredResourceAccess 参数中可以有多个对象

结语

这篇文章的篇幅较长,我尽可能详细地展示了很多Azure AD中注册应用程序,绑定服务和设定权限的细节,尤其是对于国内的Office 365客户以及合作伙伴来说应该有较高的实用价值。 当我们没有图形化界面可以使用的时候,你就会由衷地感慨,脚本(例如PowerShell)确实是很强大的,而且通过脚本的探索过程,你可以更加清晰地理解其背后的逻辑。

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

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

相关文章

Python3 学习系列 丨 博客目录索引

整个博客有关 Python 学习目录索引,方便快捷定位查询基础学习篇 Python3 基础学习笔记 C01【变量和简单数据类型】Python3 基础学习笔记 C02【列表】Python3 基础学习笔记 C03【操作列表】Python3 基础学习笔记 C04【if 语句】Python3 基础学习笔记 C05【字典】Pyt…

【转】日邮物流:实现智慧物流,这个云上对了!

和阳光、空气、水、网络一样,「物流」早已成为当代企业、个人赖以生存的必要条件。2020第一季度全球物流受疫情影响面临挑战,业内普遍预计全球物流及供应链将重新优化布局。借此时机,物流业纷纷将目光投向“数字化智慧物流”方向,…

Python 实现十大经典排序算法

目录排序算法分类一、冒泡排序(Bubble Sort)1、原理2、步骤3、动画演示4、代码实现5、具体示例二、选择排序(Selection Sort)1、原理2、步骤3、动画演示4、代码实现5、具体示例三、插入排序(Insertion Sort&#xff09…

【转】Microsoft Graph 桌面应用程序

桌面应用程序,在我这篇文章的语境中,我是特指在Windows桌面上面直接运行的.NET应用程序,包括Console Application,WPF Application,Windows Forms Application, UWP Application,并且限于篇幅,我…

【转】Microsoft Graph Web应用程序极致开发体验

前言 这篇文章最早写于2017年5月2日,当时的想法是从最简单的方式来写如何在一个ASP.NET MVC应用程序中集成Microsoft Graph,但实际上还真不是那么简单,至少我是不满意的,加上这一两周都比较忙,所以这一篇就一直搁置。…

Spark(idea)操作mysql进行查询和插入 (代码+理解)

首先在maven中加入配置 <!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.27</version></dependency>然后在idea配置数据库 1&#xff09; 查询 //1.查询数…

【转】在无人值守程序(服务)中调用Microsoft Graph

什么是无人值守程序&#xff08;服务&#xff09; 我在此前用了几篇文章分别介绍了在桌面应用程序&#xff08;控制台&#xff09;&#xff0c;Web应用程序&#xff08;ASP.NET MVC&#xff09;&#xff0c;以及PowerSehll脚本中如何访问Microsoft Graph&#xff0c;今天这一篇…

【转】使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇

前言 在上一篇文章 基于Office 365的随需应变业务应用平台 中我提到&#xff0c;随着随需应变的业务需要&#xff0c;以及技术的发展&#xff0c;业务应用的开发的模式也有了深刻的变化。基于微软的平台&#xff0c;有服务于主干业务应用的Dynamic 365 业务应用平台&#xff0…

Spark内核源码学习(暂未学完)

1&#xff09; 回顾 1.1 Spark通用运行流程概述 在submit任务条件是需要指定executo个数&#xff0c;executor-CUP个数&#xff0c;可以提高并行度。 什么是并行&#xff0c;什么是并发&#xff1f; 并发&#xff1a;假如有多个任务task&#xff0c;并行是在一个cup中&#x…

【转】使用PowerApps快速构建基于主题的轻业务应用 —— 进阶篇

在上一篇 使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇 中&#xff0c;我用了三个实际的例子演示了如何快速开始使用PowerApps构建轻业务应用&#xff0c;你可能已经发现&#xff0c;我都是使用默认生成的设置&#xff0c;没有做任何修改。当然&#xff0c;那样做出…

Spark一些组件的定义

Driver program: 运行应用程序的main函数并创建SparkContext的进程 除了RDD的最终执行所写的业务逻辑&#xff0c;剩下的都在Driver里生成&#xff0c;Driver端执行action算子才会到开始执行所创建的DAG-RDD图。 Cluster manager&#xff1a; 用于获取集群资源外部服务 Mas…

【转】D365 FO第三方集成(二)---访问认证(获取访问令牌)

D365 FO 在github上发布了第三方访问D365 FO的示例代码&#xff0c;里面包含了各种调用示例&#xff0c;代码很清晰。https://github.com/microsoft/Dynamics-AX-Integration 这篇blog简单分析一下代码中获取访问令牌的部分代码。 与获取访问令牌相关的代码有两个类ClientConfi…

【转】D365 FO第三方集成(三)---服务实现

D365 FO的Custom Service的实现比AX2012简单了很多。 AX2012服务方法要用属性SysEntryPointAttribute标记&#xff0c;添加到Services以后&#xff0c;还要发布服务并在系统管理入站端口添加操作&#xff0c;服务运行在CIL下&#xff0c;所以每次改动服务方法的代码都要增量生成…

PHP连接sql seaver数据库

我的PHP版本7.0 通过sqlsrv系列函数&#xff0c;需要下载安装Microsoft Drivers for PHP for SQL Server驱动&#xff1a; 地址&#xff1a;https://msdn.microsoft.com/library/dn865013.aspx。 根据自己需求下载安装&#xff0c;安装地址php下ext目录下&#xff0c;我的是4.0…

NoSql理解+传统关系型数据库ACID+Nosql的CAP+BASE的理解

1&#xff09;什么是Nosql NoSQL(NoSQL Not Only SQL )&#xff0c;意即“不仅仅是SQL”&#xff0c; 泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系数据库在应付web2.0网站&#xff0c;特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显…

ztree 点击重载 layui table

ztree 点击重载 layui table <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <HTML> <HEAD><TITLE> ztree_demo </TITLE><meta http…

数据结构与算法 - 稀疏数组(理解+代码实现案例)

举例 稀疏数组第一行是原数据几行几列和几个有效数据的个数 下面的行是各个有效数组的行列与具体值 稀疏数组实现 代码实现 package DataStructures.sparsearray;/*** 二维数组转稀疏数组 与 稀疏数组转成二维数组*/ public class SparseArray {public static void main(Stri…

数据结构 - 队列(非环形队列,以及优化成环形队列)

1&#xff09;队列的定义与实现形式-方式 2&#xff09;队列实现思路&#xff08;非环形&#xff0c;下面进行优化&#xff09; 3&#xff09;代码实现&#xff08;注意并不是环形&#xff09; package DataStructures.queue;import java.util.Scanner;/*** 使用数组模拟队列*…

爬取网易云音乐歌曲特色榜单信息

网易云音乐(iframe内的歌单) 刚开始学习做下记录 需要先下载好所需浏览器内核 我时谷歌&#xff0c;下载地址 http://chromedriver.storage.googleapis.com/index.html 然后没了&#xff0c;自己F12扒拉下就行了 运行&#xff1a; 左侧随便点击一个榜单后&#xff0c;复制ur…

数据结构 - 单链表(Linked List)实现在内存中实现数据以链表形式生成并根据序号排序

下面实现一个例子来进行学习 1&#xff09;介绍 单链表的逻辑结构 在内存中的实际结构 具体创建示意图&#xff1a; 2&#xff09;代码实现 例子 1。第一个程序在添加的时候并没有按照序号排序&#xff0c;如果在添加的时候把位置改变输出的时候序号会改变 package DataStr…