Monday, December 28, 2020

In the dungeons of Azure AD B2B: prevented that external can have multiple active guest accounts on alternative email addresses

A charm of Azure AD B2B is that the responsibility for guests account management is federated to the external context of invited person. But with this charm inevitable also comes lesser direct control, as within the inviting tenant you have no insight on the federated account in the external Azure Active Directory. I wrote already on a negative effect that can result from this: properties of external Azure AD account might block creation of guest account.
Recent I experienced a peculiar variant of this issue. An external was successful invited, and able to redeem the provisioned guest account and use that to access resources in the inviting tenant. At a later moment, the same external was reinvited via New-AzureADMSInvitation cmdlet on an alternative email address as identity. This was also successful and resulted in a second guest account provisioned in the inviting tenant. But when trying to resend the redeem invitation from Azure Portal, this failed as the new guest account on deeper level is referring to the same federated external identity as the original provisioned guest account. Thus although it looked in the inviting tenant that the 2 guest accounts were isolated from each other, in the reality of the actual identity source of the invited external the 2 alternative emails are administrated as proxy addresses within the same external Azure AD account.
I consider it as correct behavior by Azure AD B2B to recognize this, and prevent that multiple guest accounts can federate to the same single external Azure AD account.
Same external invited with 2 separate guest accounts in inviting tenant
Initial guest account successful accepted and activated
Later provisioned guest account cannot be accepted
Reinvite via Azure Portal blocked as guest account is referring to same external Azure AD account

Tuesday, December 22, 2020

Developer inconvenience: Deploy Isolated WebPart with webApiPermissionRequests fails unless permission to create new Azure AD App Registration

In real-life enterprise context, it is advised to tag any SPFx webparts that will invoke an Azure AD protected API as isolated. This to prevent that other script running in same page, can abuse the OAuth access token assigned to the SPFx webpart and invoke any tenant-wide API permissions on behalf of current user.
However, you need to be aware of some deployment implications with Isolated WebParts. The first one is that in the Microsoft design, you can only deploy Isolated WebParts via the tenant AppCatalog. It is not possible to deploy an Isolated WebPart (only) to the site App Catalog where it will actualy be used. I suspect this is due that each Isolated SPFx WebPart creates a new Azure AD App Registration on tenant level, and for consistency the SPFx WebPart must therefore also be installed on tenant level. Negative result is that every site-specific customization is visible on all others sites where it likely is unusable. Luckily this visibility is initial limited to only the site owners in "Add an App". Only after a site owner explicit adds the Isolated WebPart to the site, then it will be visible in page editing mode in the available WebParts.
An even more significant inconvenience is that to successful deploy an Isolated WebPart, you need to have the authorization to create a new Azure AD App Registration. Without that permission, the deployment in tenant AppCatalog will fail with the generic error 'Deployment failed. Correlation Id ....'. Implication is that in effect the dependency on Ops is unnecessarily increased: a developer must reach out to a Global Admin for the deployment of SPFx solution containing Isolated WebPart. But the better option is that you request that Global Admin to assign your account the Application Developer role, then you are empowered to do this 'Ops' part yourself.

Sunday, December 13, 2020

Simple pattern to ensure unique element ID inside SPFx React WebPart

When you build a SharePoint WebPart, you must take into account that the business user can add multiple instances of that webpart on a single page. So the operational execution must be robust for that. In case your webpart relies on HTML element ID, e.g. via 'getElementbyId', then you must ensure that the element ID of each instance is unique. A simple pattern I applied is to derive the ID of the inner React Component on that of the unique ID of the parent React WebPart.
Part 1: Extend the React WebPart Properties interface with a property for unique ID
Part 2: Parent React WebPart derives unique ID from its own, and pushes to the inner React Component
Part 3: Inner React Control applies the received unique ID in its rendering + operation

Sunday, November 8, 2020

Office Graph and Microsoft Graph

Clear and consistent product naming remains a challenge, certain also in the Microsoft domain. An example is the reuse of phrase 'Graph' in Office Graph and Microsoft Graph aka Graph API. What do these names entail, and what if any is the relation?

Office Graph

Office Graph is the oldest name, and originates in 2014 as the foundation underlying Delve. "The brains behind Delve is the Office Graph. The Office Graph continuously collects and analyses signals that you and your colleagues send when you work in Microsoft 365. For example, when you and a colleague modify or view the same document, it’s a signal that you’re likely to be working together. Other signals are who you communicate with through e-mail, and who you’ve shared documents with, who your manager is, and who has the same manager as you."

Microsoft Graph aka Graph API

Microsoft Graph is a giant proxy, it takes requests in, validates authentication token, optional does validation and transformation, and then passes / forwards to the specific inner layer in Microsoft 365 landscape; and returns the inner responses, optional after transformation to the Graph API caller. Graph API provides consistency over all the different inner services, on level of authentication, property naming and casing, exception handling, singular shared object types (eg consolidate on one definition of ErrorDetails object type). Important to understand is that Microsoft Graph itself does not provide services, it simple delegates to the actual services in the Microsoft 365 landscape.

Actual the same?

Microsoft: "The Microsoft Graph models activity in Microsoft 365 services, including Exchange Online, SharePoint Online, Yammer, Skype for Business, Azure Active Directory, and more, and in external services, such as other Microsoft services or third-party services. Microsoft Graph components are used throughout Microsoft 365. The Microsoft Graph represents a collection of content and activity, and the relationships between them that happen across the entire Office suite. It uses sophisticated machine learning techniques to connect people to the relevant content, conversations and people around them. The Microsoft Graph contains information about enterprise objects, such as people and documents, as well as the relationships and interactions among these objects. The relationships and interactions are represented as edges."

Office Graph renamed into Microsoft Graph

The Office Graph has evolved to become exposible via the Microsoft Graph. Thus they have conceptual morphed into same offering, Office Graph as backend collects and analyses signals that you and your colleagues send when you work in Microsoft 365; and the Graph Api provides central gateway access to this collected information. And also to all other services within Microsoft 365 landscape.
Graph API on top of Microsoft Graph administration of collected signals in Microsoft 365 landscape and services
The Microsoft Graph Insight APIs expose relationships generated by Office Graph services (source: Microsoft Search 101 - What’s the relationship between the Microsoft Graph and Office Graph?, Bill Baer)

Friday, October 16, 2020

Tip: how-to self-produce without external encoder into MS Stream Live Event

Webcast production for a Microsoft Stream Live Event is default tied to external encoder. Teams Live Event supports this also, but defaults to simple self-production via Teams App itself. In that case, the live event is not distributed via Stream; nor is the event recording stored within MS Stream. Instead Teams uses its internal Azure Media Services based streaming, and stores the recording somewhere for period of max 180 days after the event is over. Yammer Live Events takes a middle road, or the best of 2 worlds. It supports the same 2 production approaches as Teams - external encoder or via Teams. However, the difference is here within the Teams production handling. Even although produced as a simple Teams Live Event, under the hood this does use Microsoft Stream for the webcast distribution and processing, and after the live event is stopped for the storage of the recording for on-demand watch.
This opens multiple advantages
  • It allows to use the simplicity of Teams production for a webcast, and still embed the video on an event portal (typical hosted via SharePoint Online);
  • It prevent the need for and availability of external encoder (e.g. Wirecast-S, TeraDeck, OBS Studio, ...);
  • Corporations that have employed Ramp Multicast+ as eCDN solution to optimize and control the webcast traffic of Stream on the corporate network, can employ this also for webcasts produced via Teams
Way to apply this approach is by:
  1. Schedule your webcast as a Yammer Live Event;
  2. Produce your webcast as a Teams Live Event;
  3. Consume / watch the webcast as a Stream Live Event.
Step 1: Schedule as Yammer Live Event
Step 2: Produce as MS Teams Live Event
Step 3: Consume as MS Stream Live Event, e.g. embedded on SharePoint Online page
Yammer channel determines who is allowed to watch the live event
Something to be aware in case you would apply this approach, is that Yammer then controls who is allowed to watch the live webcast. Namely the members of the Yammer channel in which the Live Event is scheduled. So you must then make sure that all the accounts that are invited as webcast audience, are invited to the 'owning' Yammer channel. It is not possible to extend via Stream portal the permissions of the scheduled Yammer (= Stream) Live Event. After the event ended, then the video recording is 'released' for video management actions through Stream portal.

Thursday, October 15, 2020

Inconvenient authorization management in 'classic' MS Stream

In the corporate usage of Microsoft Stream as Enterprise Video Portal (EVP), authorization to watch videos is also applied on 'need-to-known' base. In current Stream, it turns out a bit inconvenient to execute effective permission management.
First issue is that it is made complex to nearly impossible to efficient configure permission management on a collection of videos. The root cause of this is in how Microsoft Stream handles the authorization and organization of the video store: "In Microsoft Stream, you can use channels and groups to organize and grant permission to your videos" [Source: https://docs.microsoft.com/en-us/stream/groups-channels-overview]. This is actually not a valid statement. Indeed Stream (aka Azure AD) groups "are both a way to organize videos and to control access to videos", but channels merely "are an organization method for videos, but not a permission method". Limiting for efficient permission management is that Stream portal does not include a capability to logical associate video(s) within either a Group or Channel, this is only supported initial on the moment of adding / uploading video(s) into Microsoft Stream. Once already stored in Microsoft Stream, the only possible way to associate video(s) with additional groups or channels it to do this per video, via the manual Add to group/channel action in the video-edit menu. When this must be done for larger collection of videos, this is a cumbersome and time-consuming effort.
Second issue is that Stream suffers from a delay before the indirect authorization assignment via Stream groups is actual applied (becomes active). In situation that authorization to watch a certain video is managed by one or more Stream groups, authorizing another person for access by adding her/his Office 365 account to an authorized group (e.g. via Azure Portal), does not immediate grant the person allowed access to the video. In reality it can take up to even an hour before the group based authorization within Stream context is updated to incorporate the new added account. Until then, the person remains confronted with Stream access denial on the video.
Even worse, similar effect occurs when revoking the access by removing from Stream group. This is neither immediate effectuated. Luckily the elapse time period is in this situation shorter, max 1 to 2 minutes; not a full hour. Still, immediate access revocation on unjustified granted video is not possible.
Perhaps within new Stream, in which the video storage moves to SharePoint Online, the authorization management improves. Not 100% confident yet, as Modern SharePoint also uses Azure AD groups for permission management. However, experiences within regular SharePoint Online usage are that any change in the Azure AD group(s) are almost immediate applied for access control, both on access assignment as revocation.

Sunday, October 4, 2020

Tip: Teams NDI® only becomes active for capture when 2nd person joins the meeting

The new NDI® capability in Teams is interesting for webcast production, as it allows that you simultaneously combine the video signals of multiple persons in the stream. An use case is for a digital (panel)conversation between 2 or more presenters, which are physical at different places. This scenario is native already possible via Teams Meeting; however then you miss the flexibility in organizing the screen layout of the webcast production. E.g. display another background, display a PowerPoint presentation, switch between picture-in-picture vs full profile; display a ticker message and so on.
As I acknowledge the usability of Teams NDI capability for productive company webcasts, I played around a bit with it: in Teams (MSDN development tenant) configured NDI capability on tenant level (Use NDI® technology in Microsoft Teams) + for own Teams account (Broadcasting audio and video from Teams with NDI® technology); webcam setup (via IVCam) on home system; OBS Studio with NDI plug-in.
While playing, I notice that the NDI signal only becomes active on the network once a second person joins in the Teams meeting. Implication of this is that as producer you cannot prepare a production setup with only you present yet in the Teams meeting. In reality this should not be an issue: the reason to use NDI for capturing is because you want to capture the video of other person or persons. Not that of yourself, that you can just as simple direct capture in OBS Studio (or other encoder) as 'video camera' input.

Screenshots of exploring Teams NDI capability

Join as webcast producer / organiser the Teams Meeting, with NDI enabled for yourself
Teams does not yet activate NDI broadcasting, while not actually a meeting of multiple persons
Second person joins the Teams Meeting
Teams now activated NDI broadcasting, and can be captured in OBS Studio
Once 2nd attendee in the meeting, Teams displays the NDI broadcasting notification