...
Warning |
---|
This page applies to Grouper 2.5. For Grouper v4+ see this page |
The Grouper Azure provisioner is a changelog consumer that synchronizes Grouper groups and users to Microsoft Azure Active Directory/Office 365. This currently only supports security or Office 365 (unified) groups. Support for mail-enabled groups is unavailable due to lack of support in the Microsoft API.
...
- can now create Office 365 (unified) groups as well as security groups
- supports more than one provisioner
- custom names, descriptions using jexl expressions
- custom mail nicknames, using jexl, for unified groups
- custom UPN, can be derived from attribute, jexl, or customizable domain
- Public, Private, and HiddenMembership options for unified groups
- ability to set up multiple provisioners with different option groups
Initialize
The provisioning attribute to add to the provisionable object is, by default, etc:attribute:office365:o365Sync
. If set on a folder, all groups under this folder (recursively) will be automatically provisioned. Alternatively, the attribute can be set on an individual group. It is not recommended to assign directly to a group, as there is currently a race condition that may occur in the current version of this code (i.e., if the changelog consumer runs after group creation but before attribute assignment, provisioning will not occur). It is also required to create attribute etc:attribute:office365:o365Id
, which will store the Azure group Id on the Grouper group to be kept in sync.
...
2. Configure loader job in grouper-loader.properties. Note that you will need to set up an application with access to your domain. See documentation at http://graph.microsoft.io/en-us/docs, and Notes for Developers below.
Code Block |
---|
changeLog.consumer.o365.class = edu.internet2.middleware.grouper.changeLog.consumer.Office365ChangeLogConsumer # fire every 5 seconds changeLog.consumer.o365.quartzCron = 0,5,10,15,20,25,30,35,40,45,50,55 * * * * ? changeLog.consumer.o365.syncAttributeName = etc:attribute:office365:o365Sync changeLog.consumer.o365.retryOnError = true changeLog.consumer.o365.tenantId = @o365.tenantId@ changeLog.consumer.o365.clientId = @o365.clientId@ changeLog.consumer.o365.clientSecret = @o365.clientSecret@ #changeLog.consumer.o365.domain = #changeLog.consumer.o365.idAttribute = #changeLog.consumer.o365.upnAttribute = #changeLog.consumer.o365.groupJexl = #changeLog.consumer.o365.mailNicknameJexl = #changeLog.consumer.o365.descriptionJexl = #changeLog.consumer.o365.subjectJexl = #changeLog.consumer.o365.groupType = [Security* | Unified] #changeLog.consumer.o365.visibility = [Public* | Private | HiddenMembership] #changeLog.consumer.o365.proxyType = [http | socks] #changeLog.consumer.o365.proxyHost = #changeLog.consumer.o365.proxyPort = |
Custom configuration parameters
tenantId, clientId, clientSecret
Replace @o365.tenantId@
, @o365.clientId@
and @o365.clientSecret@
with appropriate values from the application configuration. Note that the clientSecret is sensitive information.
domain
Property domain defines the domain name to be used with user principals. If not defined, the tenantId property will be used to construct user principals.
idAttribute
Optional property idAttribute
specifies what attribute is used to build the Azure user principal, and will default to "uid" if not set. The Azure principal will get built as idattribute + "@" + domain or tenantId. Whatever attribute is used must be available as a key in the set returned in subject.getAttributes()
; i.e., if you want to use the subject's id or identifier, it needs to be defined in the subject attributes too.
upnAttribute
If subjects reliably have the Azure principal name as one of their attributes, setting upnAttribute will use this value as is to identify Azure users, rather than calculating it through other methods.
groupJexl, mailNicknameJexl, and descriptionJexl
Optional *Jexl properties support jexl2 expressions in deriving custom values. Variable group
is provided to the group jexl expressions, while subject
and subjectIdValue
are for subjectJexl. Variables common to both are consumerName
, tenantId
, domain
, and idAttribute
. Brackets are not needed around the expression.
...
The defaultIfExpressionNull parameter is intended mainly for internal code to avoid extra tests for a null expression.
groupType, visibility
The optional groupType
property can set the provisioned groups as either a security group (groupType = Security
) or an Office 365 group (groupType = Unified
). If not set, the default will be a security group. Mail-enabled groups are not currently available, as they cannot be set through the Microsoft web service API.
For a Unified group provisioner only, the visibility
property sets the Office 365 visibility. Possible values are Public (default), Private, or HiddenMembership*. See Microsoft's documentation on the option and also the GitHub documentation for more information.
proxyType, proxyHost, proxyPort
If the daemon server requires a proxy to access the internet, a HTTP or SOCKS proxy can be defined using proxyType
, proxyHost
, and proxyPort
. Currently, the SOCKS5 proxy only supports anonymous access.
Fallback methods for subject principal name calculations
Methods for determining the subject principal will try properties in the following order, when they are defined. If a method returns null or blank, the next method will be tried.
...
If all three methods return blank values, a runtime exception will be thrown.
Multiple Provisioners
It is possible to set up multiple Azure provisioners, each with different settings. One scenario for this would be to have one folder for security groups and another for Office 365 groups. Or, different folders can have different Jexl expressions, etc. To distinguish them, they need separate consumer attributes created. Then, each loader configuration would reference their respective attribute names, and folders would set the distinguishing syncAttributeName attribute to select a provisioner. Other required properties need to be repeated for each provisioner For example:
Code Block |
---|
# Creates security groups changeLog.consumer.o365.class = edu.internet2.middleware.grouper.changeLog.consumer.Office365ChangeLogConsumer changeLog.consumer.o365.tenantId = my-tenant.onmicrosoft.com changeLog.consumer.o365.clientId = ... changeLog.consumer.o365.clientSecret = ... ... changeLog.consumer.o365.syncAttributeName = etc:attribute:office365:o365Sync changeLog.consumer.o365.groupJexl = ... # Creates Office 365 groups changeLog.consumer.o365Unified.class = edu.internet2.middleware.grouper.changeLog.consumer.Office365ChangeLogConsumer changeLog.consumer.o365Unified.tenantId = my-tenant.onmicrosoft.com changeLog.consumer.o365Unified.clientId = ... changeLog.consumer.o365Unified.clientSecret = ... ... changeLog.consumer.o365Unified.syncAttributeName = etc:attribute:office365:o365SyncUnified changeLog.consumer.o365Unified.groupType = Unified changeLog.consumer.o365Unified.visibility = Private |
Install
The Java library and its dependencies are included with the Grouper container >=2.5.26. But it should be usable with earlier Grouper 2.4 or 2.5 versions by downloading and adding the required libraries. Those libraries are:
...
Grouper containers 2.5.16 through 2.5.25 ship with an earlier version of the grouper-azure-provisioner.jar. If you happen to be running these versions, you should upgrade to 2.5.26 or greater.
Office 365 Notes for Developers
Login to the app management console:
...
https://login.microsoftonline.com/$TENANT/adminconsent?client_id=$APPLICATION_ID
Graph API Notes
To get a token for making Graph API calls, do the following:
...
- client_secret - specify password generated from "Generate New Password" above
- client_id - specify Application Id that's generated when creating app
- grant_type - specify client_credentials, this value implies "Application Permissions" (as opposed to "Delegated Permissions")
- redirect_uri - specify http://localhost/grouper
- scope - specify https://graph.microsoft.com/.default
Official description of relevant group fields (from Microsoft)
Maximum lengths for displayName, description, and mailNickname for provisioned groups must be within the length limits as described by Microsoft (https://github.com/microsoftgraph/microsoft-graph-docs/blob/master/api-reference/v1.0/api/group-post-groups.md), otherwise group creation will fail.
Property | Type | Description |
displayName | string | The name to display in the address book for the group. Maximum length: 256 characters. Required. |
description | string | A description for the group. Max. length: 1024 characters. Optional. |
mailEnabled | boolean | Set to true for mail-enabled groups. Required. |
mailNickname | string | The mail alias for the group. Max. length: 64 characters. Required. |
securityEnabled | boolean | Set to true for security-enabled groups, including Office 365 groups. Required. |
owners | string collection | This property represents the owners for the group at creation time. Optional. |
members | string collection | This property represents the members for the group at creation time. Optional. |
visibility | String | Specifies the visibility of an Office 365 group. Possible values are: Private, Public, HiddenMembership, or empty (which is interpreted as Public). |
Acknowledgments
The Office365/Azure provisioner for Grouper originated as a project from Unicon, Inc. Primary developers were Bill Thompson, Jj!, and John Gasper, with other contributions by Chris Hyzer and Russ Trotter. The source project can be found at https://github.com/Unicon/office365-and-azure-ad-grouper-provisioner.
...