LPS:IdM/midPoint/Office365

Z HelpDesk

Info

Microsoft Office365 - cloudová aplikace. Identity jsou spravované přes Graph API.

Admin přístup pro IdM

  1. https://office365.zcu.cz
  2. Admin Center -> Azure Active Directory -> Azure Active Directory -> App registrations
  3. identita "OpenICF MSGraph Connector" -> Client credentials

==> hlavní ID použít Application (client) ID

==> heslo použít secret z Client credentials

==> (lze si zvolit dobu platnosti, ale max. je 2 roky)

Konektor

Máme vlastní fork s drobnými odlišnostmi:

  • jiné závislosti pro runtime a build (podobné verze s midPointem na ZČU)
  • do upstramu jsme přispěli vlastními změnami (optimalizace, opravy, podpora licencí)

Model

kind objectClass intent focus význam
account AccountObjectClass - UserType osoba
entitlement GroupObjectClass group OrgType skupiny (nepoužíváme)
generic CustomlicenseObjectClass license OrgType licence

Osoby

Zaměstnanci, studenti, rozšířená hostovská konta (je vyžadováno CRO ID).

Primární klíče:

  • __NAME__ - LOGIN@DOMAIN
  • onPremisesImmutableId - CRO ID (nikdy se nesmí měnit)
  • userPrincipalName - LOGIN

Atributy:

  • mail: LOGIN@DOMENA, jen přo zakládání, ale nelze spravovat přes Graph API
  • proxyAddresses: jen ke čtení. Obsahuje e-mailové adresy. Tímto atribuem lze detekovat potíž po přejmenování, kdy je potřeba ruční zásah.
  • password:
    • povinné, i když se nepoužívá
    • nesmí obsahovat příliš speciální znaky
    • generujeme náhodné, aby tam něco bylo

Merge: nelze

Povolení/blokace: 1:1 podle identity v midPointu

Přesměrování e-mailů: nelze spravovat přes Graph API. Nastavování přesměrování ve skriptech mimo režii IdM.

Přejmenování: potřeba ruční zásah kolem správy emailů. Původní email je u přejmenovávané identity ponechán. Existují ruční postupy přes skripty, jak to čistit.

Fyzické mazání: Pro konta ve stavu BD (blokované 2 roky). Po smazání je identita v koši po dobu 1 měsíce. Po tuto dobu ji nelze znovuzaložit automaticky přes Graph API. Lze ji obnovit přes administrátorské rozhraní Office 365, anebo smazat vývojovými administrátorskými nástroji (koš nelze vysypat přes midPoint - umí to Graph API, ale identity mají divoké identifikátory).

Skupiny

Z IdM neudržujeme, teoreticky je možné.

Licence

Read-only identity. V midPointu použito pro výpočty atributů pro přidělováné licencí (technicky: jde o "ruční" query, nelze použít přímo asociace na resourcu).

Licence se skládá z jednotlivých aplikací.

Pro každou licenci lze nastavit globální vyjímku pro nějakou aplikaci. Ale nelze nastavovat různé vyjímky pro každého uživatele (technicky: přes Graph API to lze, ale vedlo by to na strukturovaný atribut u uživatele).

Výpočet licencí

Princip

Šílenost. Vychází se z dokumentu: https://software.zcu.cz/files/MS_EES.html

V zásadě dva typy licencí: A1 a A3 a každá z nich má studentskou a zaměstnaneckou verzi.

  1. Typ studentské se volí podle fakulty (==> GROUP: o365proplus-students)
  2. Typ zaměstnanecké podle self-managementu (SELF: O365 PRACOVISTE), ale jen pro vybraná pracoviště (==> GROUP: o365proplus-PRACOVISTE). Mimofakultní mají ještě rozdělený self-management, ale slévají se do jednoho GROUP: o365proplus-rek. Pak je ještě MNG: O365 SPECIAL pro zaměstnaneckou A3 licenci bez hlídání, zda jde o zaměstnance na správném pracovišti (např. i hostovská konta).
  3. Přičítá se ještě PowerBI Pro na základě ručně udržované skupiny MNG: O365 PowerBi Pro (==> GROUP: o365powerbipro) (poznámka: ta self skupina by tu být nemusela, nikdo nemá přístup)

Nelze kombinovat studentskou a zaměstnaneckou licenci (body (1) a (2)), studentská má vždy přednost.

Role v midPointu

GROUP: o365proplus-PRACOVISTE:

  • výsledné skupiny pro vyšší licence (A3) pro jednotlivá pracoviště
  • automatický výpočet se chytá na název skupiny s prefixem o365proplus- v unix názvu
  • indukuje se ze self-management skupin, ale i automaticky
  • přiřazení je aktivní pouze pro zaměstnance daného pracoviště

GROUP: o365proplus-students:

  • výsledná skupina pro studenty, co mají mít vyšší licenci (A3)
  • vyjímky přidatelné v Grouperu ve skupině mng:o365StudentSpecial

GROUP: gapps:

  • výsledná skupina pro speciální případy pro standardní licence (A1)
  • řídí se jí Google Apps i Microsoft 365

GROUP: office365:

  • XXX: zřejmě historická již nepoužívaná skupina

SELF: O365 XXX:

  • skupiny, kam se lze přihlásit přes self-management
  • obsahuje IdM atribut requestableGroups, který obsahuje seznam vyžadovaných skupin v LDAPu, aby se šlo do skupiny přihlásit (vč. negací)
  • indukuje se dál do hlavních skupin, ale s hlídáním příslušností

SELF: gapps:

  • skupina, kam se lze přihlásit hostovským kontem nebo aktivním kontem s běžící expirační dobou (A2-A4)
  • obsahuje IdM atribut requestableGroups, který povolí takováto konta
  • XXX: pro uživatele trochu matoucí název, jako by tam měli být všichni s přístupy, ale slouží jen pro A2 konta

MNG: O365 XXX:

  • stejný princip jako SELF: O365 XXX, self-management je vidí, ale nelze se do ní přihlásit
  • liší se prázdným atributem requestableGroups
  • zvolen jiný název, aby se nepletlo s běžnými self-management skupinami (název je vidět jen interně v midPointu)

Skripty

Počáteční import (aktualizovaný):

# === studenti ===
./group.py.fixme o365proplus-students -s "Licence Microsoft pro všechny studenty"

for fak in fdu fst fel fav fpe; do ./modify-role.py -q subtype=stag-global-group-student extension/ext:GROUP_ZKRATKA=${fak^^} -a role-group-o365proplus-students:role; done

# === per fakulta ===
# 1) self role
for fak in fdu fst fel fav fpe rek-ntc rek-civ rek-ps rek-uk rek-ujp rek-rek rek-skm rek-suz; do
	FAK=${fak^^}
	FAK=$(echo $FAK | tr '-' '/')
	org=$(echo $fak | cut -d - -f2)
	ORG=${org^^}

   ./create-role.py "name=SELF: O365 $FAK" displayName="o365proplus-$fak" description="Licence pro Microsoft365 (A3plus) - $ORG" extension/ext:requestableGroups=staff requestable=true -a "$(./query-archetype.py name='ZCU Self Management Role' --oid):archetype"
done
# tune catchall REK
rekoid="$(./query-role.py name='SELF: O365 REK/REK' --oid)"
./modify-role.py --oid $rekoid 'extension/ext:requestableGroups+=!civ'
./modify-role.py --oid $rekoid 'extension/ext:requestableGroups+=!ps'
./modify-role.py --oid $rekoid 'extension/ext:requestableGroups+=!suz'
./modify-role.py --oid $rekoid 'extension/ext:requestableGroups+=!uk' 
# special
fak=special; FAK=${fak^^}; org=$fak; ORG=$FAK;
./create-role.py "name=MNG: O365 $FAK" displayName="o365proplus-$fak" description="Licence pro Microsoft365 (A3plus) - $ORG" extension/ext:requestableGroups+=nobody requestable=false -a "$(./query-archetype.py name='ZCU Self Management Role' --oid):archetype"

#./query-org.py extension/ext:OU_ZKRATKA=$FAK 'subtype=hr-org-str' | head -n 3
##==> OID
#oid=
#./modify-org.py --oid $oid -i role-group-o365proplus-${fak}:role

# 2) output roles (groups)
for fak in fdu fst fel fav fpe special; do
	ORG=${fak^^}
	./create-role.py name="GROUP: o365proplus-$org" subtype=group  description="Licence Microsoft pro zaměstnance $ORG" displayName="GROUP: o365proplus-$org" identifier="o365proplus-$org" -a $(./query-role.py --oid name="ZCU: Posix Group"):role -a $(./query-archetype.py --oid name="MidPoint: Legacy Group"):archetype
done
ORG=REK; ./create-role.py name="GROUP: o365proplus-$org" subtype=group  description="Licence Microsoft pro zaměstnance $ORG" displayName="GROUP: o365proplus-$org" identifier="o365proplus-$org" -a $(./query-role.py --oid name="ZCU: Posix Group"):role -a $(./query-archetype.py --oid name="MidPoint: Legacy Group"):archetype

# 3) self / output connections
for fak in fdu fst fel fav fpe special; do
	./modify-role.py --oid role-self-o365proplus-$fak -a role-group-o365proplus-${fak}:role
done
for org in ntc civ ps uk ujp rek skm suz; do
 ./modify-role.py --oid role-self-o365proplus-rek-${org} -a role-group-o365proplus-rek:role
done

Ručně přidat do každé self-management role pro assignment výstupní role (dodatečná kontrola při rušení autorizace):

		<condition>
			<source>
			   <path>$source/name</path>
			</source>
			<source>
			   <path>$source/extension/requestableGroups</path>
			</source>
			<expression>
				<script>
					<relativityMode>absolute</relativityMode>
					<code>
						return zcuUtils.execute('authRequestable', [
							'userObj': focus,
							'roleName': name,
							'requestableGroup': requestableGroups,
						]);
					</code>
				</script>
			</expression>
		</condition>

CA

# C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
keytool -importcert -keystore ./keystore.jceks -file /usr/share/ca-certificates/mozilla/DigiCert_Global_Root_G2.crt -alias digicert-g2
# C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
keytool -importcert -keystore ./keystore.jceks -file /usr/share/ca-certificates/mozilla/DigiCert_Global_Root_CA.crt -alias digicert-ca

(starší postup byl: https://www.microsoft.com/pki/mscorp/cps/default.htm + import např. M$ CA1, CA2, CA4 a CA5)

Postupy

Hostovská konta

Postup přidání přístupu pro hostovská konta:

  1. přidělit CRO ID, viz LPS:IdM/midPoint#Přidělení CRO ID
  2. zařadit do role SELF: gapps (nastaví Google Apps a licenci pro Office365, ale Office365 se musí explicitně přiřadit)
  3. TODO: GROUP: office365 je historická skupina a zřejmě se již na nic nevyužívá (speciální přístupy před změnami kolem licencí 2021-06)

Vyrobení licence

Ručně spravované nebo self-management licence lze zakládat bez nutnosti modifikace workflow kódu v midPointu. Takto lze řešit pouze licence, co se nepočítají dynamicky a je to bez závislostí mezi ostatními licencemi.

Postup:

# název k nalezení v admin sekci M365: Billing -> Licences
name="Project Plan 3 Faculty"
documentation="https://rt.zcu.cz/rt/Ticket/Display.html?id=..."
display=o365-projectplan-faculty
./create-role.py -a $(./query-archetype.py name='ZCU Self Management Role' --oid):archetype:org:default "name=MNG: O365 $name" displayName="$display" description="Licence pro Microsoft365 ($name)" documentation="$documentation" extension/ext:requestableGroups=nobody requestable=false

Přidat sekci: (kde ... je název licence z Graph API, k nalezení v organizační struktuře licencí)

<inducement>
    <focusMappings>
       <mapping>
          <name>License</name>
          <authoritative>true</authoritative>
          <strength>strong</strength>
          <expression>
              <value>...</value>
          </expression>
          <target>
              <path>$focus/extension/office365Licenses</path>
          </target>
       </mapping>
    </focusMappings>
</inducement>

License PowerBi Pro

Řídí se v IdM rolí MNG: O365 PowerBi Pro. Lze nastavit v assignments přímo v IdM nebo přes příkazový řádek.

Přidání přes příkazová řádek (nahradit $LOGIN za login):

./modify-user.py -q name=$LOGIN --assign "$(./query-role.py 'name=MNG: O365 PowerBi Pro' --oid)":role

Odebrání přes příkazový řádek (nahradit $LOGIN za login):

./modify-user.py -q name=$LOGIN --unassign "$(./query-role.py 'name=MNG: O365 PowerBi Pro' --oid)":role

Issues

  • po založení uživatele následný get selže, protože uživatel se objeví až po delší době
    • obchází se na úrovni konektoru správnou reakcí na chyby a tolerantnějším nastavením reakcí na chyby v midPointu
  • konflikt mezi skupinami a osobami kvuli e-mailové adrese
    • čas od času se nějaká identita nezaloží