Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Navitabs
rootSecurity API - Leverancebeskrivelse
includeroottrue


Dette dokument beskriver NSP Security API til brugerautentificering og autorisering på NSP.

Først vises hvordan NSP Security API rent praktisk indføres i en NSP komponent med konkrete eksempler på anvendelse.

Denne sektion er især relevant for udviklere, der skal bruge NSP Security API i forbindelse med en konkret opgave. Det anvendelsesorienterede afsnit Dette dokument er delt op i følgende underafsnit:

  1. Tekniksk anvendelseTeknik
    1. Dependency management: Viser, hvordan Maven dependency management samt deployment descriptors til NSP base Docker image anvendes til at få de nødvendige afhængigheder på plads for anvendelse af NSP Security API.
    2. Snitfladebeskrivelser og fejlhåndtering
  2. Brugermodellering og mapning: Viser, hvordan en komponent kan anvende håndtagene i NSP Security API til at verficere indkommende kald. Herunder også dokumentation.

...

Teknisk anvendelse af NSP Security API i NSP komponenter

For at anvende NSP Security API i en konkret NSP komponent i udviklingsmæssig sammenhæng, så er der et par tekniske øvelser, der skal være på plads. Da hovedparten af NSP'ens komponenter er bygget op på samme måde, så vil denne vejledning umiddelbart kunne anvendes i langt de fleste tilfælde. Antagelsen i denne vejledning er derfor at:

...

I de følgende afsnit gennemgåes først, hvordan en komponent forberedes teknisk til at kunne anvende NSP Security API ved at udtrykke både en kodemæssig og en afviklingsmæssig afhængighed til NSP Security API.

Dernæst vises det med et praktisk eksempel hentet fra DROS og Dokumentdelingsservicen, hvordan NSP Security API bliver anvendt i dokumentation og applikationskode til at implementere brugerautentificering og -autorisation.

Det er vigtigt at notere sig, at eksempler i denne anvenderguide er ment som inspiration til anvendere af NSP Security API. Det er således ikke en udtømmende facitliste. Anvendelsen af NSP Security API kræver komponentspecifikke og forretningsspecifikke overvejelser:

  • Hvilke brugertyper er til stede i min komponent?
  • Hvordan skal disse brugertyper tjekkes/mappes i forhold til de forretningsregler, der gælder i min komponent?

Teknisk opsætning og anvendelse af NSP Security API

I forgående afsnit blev det fremhævet, at det ikke er en NSP komponents ansvar selv at inkludere NSP Security API i dens færdigbyggede modul.

I stedet udtrykker komponenten, at den regner med, at de omgivelser, hvori den efterfølgende afvikles, stiller NSP Security API til rådighed på afviklingstidspunktet.

Maven Dependency Management

Langt de fleste NSP komponenter anvender Maven til at holde styr på afhængigheder til tredjeparts biblioteker.

NSP Security API adskiller sig ikke fra andre tredjeparts biblioteker i den forstand og kræver således blot, at følgende tilføjes til rækken af dependencies (NB! tjek versionsnummer i forhold til den gældende version) i konfigurationsfilen (pom.xml):

Code Block
languagexml
<dependency>
    <groupId>dk.sds.nsp.security</groupId>
    <artifactId>security-api</artifactId>
    <version>1.0.6</version>
    <scope>provided</scope>
</dependency>

Det er vigtigt at notere sig, at afhængigheden til NSP Security API skal have provided scope.

Provided scope i Maven benyttes til at udtrykke en afhængighed til et library uden dette inkluderes i det færdigbyggede modul (jar/war), men som i stedet antages at blive stillet til rådighed (provided) af de omgivelser, som modulet afvikles i.

Afviklingsomgivelserne for en NSP komponent er Wildfly (evt via et af NSP'ens Docker images). I det følgende afsnit vises, hvordan man sørger for, at Wildfly rent faktisk stiller NSP Security API til rådighed for den anvendende komponent og derved opfylder kontrakten, som blev udtrykt i Maven konfigurationsfilen.

Wildfly Dependency Management

Afviklingsomgivelserne for en standard NSP komponent er Wildfly (evt via et af NSP'ens Docker images). På Wildfly findes en række tredjeparts biblioteker, der leveres med platformen - herunder også NSP Security API.

Som default er de fleste af disse bibliotekter afskærmet og således ikke til rådighed for komponenten på afviklingstidspunktet - men via en særlig konfigurationsfil (som Wildfly forstår) kan det udtrykkes, at komponenten ønsker, at få adgang til et eller flere af disse biblioteker.

For at Wildfly stiller NSP Security API til rådighed for en komponent skal filen /src/main/webapp/WEB-INF/jboss-deployment-structure.xml findes i Maven projektet og i det byggede modul og have følgende indhold:

Teknisk opsætning og anvendelse af NSP Security API

I forgående afsnit blev det fremhævet, at det ikke er en NSP komponents ansvar selv at inkludere NSP Security API i dens færdigbyggede modul.

I stedet udtrykker komponenten, at den regner med, at de omgivelser, hvori den efterfølgende afvikles, stiller NSP Security API til rådighed på afviklingstidspunktet.

Maven Dependency Management

Langt de fleste NSP komponenter anvender Maven til at holde styr på afhængigheder til tredjeparts biblioteker.

NSP Security API adskiller sig ikke fra andre tredjeparts biblioteker i den forstand og kræver således blot, at følgende tilføjes til rækken af dependencies (NB! tjek versionsnummer i forhold til den gældende version) i konfigurationsfilen (pom.xml):

Code Block
languagexml
<dependency>
    <groupId>dk.sds.nsp.security</groupId>
    <artifactId>security-api</artifactId>
    <version>1.0.6</version>
    <scope>provided</scope>
</dependency>

Det er vigtigt at notere sig, at afhængigheden til NSP Security API skal have provided scope.

Provided scope i Maven benyttes til at udtrykke en afhængighed til et library uden dette inkluderes i det færdigbyggede modul (jar/war), men som i stedet antages at blive stillet til rådighed (provided) af de omgivelser, som modulet afvikles i.

Afviklingsomgivelserne for en NSP komponent er Wildfly (evt via et af NSP'ens Docker images). I det følgende afsnit vises, hvordan man sørger for, at Wildfly rent faktisk stiller NSP Security API til rådighed for den anvendende komponent og derved opfylder kontrakten, som blev udtrykt i Maven konfigurationsfilen.

Wildfly Dependency Management

Afviklingsomgivelserne for en standard NSP komponent er Wildfly (evt via et af NSP'ens Docker images). På Wildfly findes en række tredjeparts biblioteker, der leveres med platformen - herunder også NSP Security API.

Som default er de fleste af disse bibliotekter afskærmet og således ikke til rådighed for komponenten på afviklingstidspunktet - men via en særlig konfigurationsfil (som Wildfly forstår) kan det udtrykkes, at komponenten ønsker, at få adgang til et eller flere af disse biblioteker.

For at Wildfly stiller NSP Security API til rådighed for en komponent skal filen /src/main/webapp/WEB-INF/jboss-deployment-structure.xml findes i Maven projektet og i det byggede modul og have følgende indhold:

Code Block
languagexml
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        <!-- NSP komponenter styrer selv logning -->
        <exclude-subsystems>
            <subsystem name="logging"/>
        </exclude-subsystems>
Code Block
languagexml
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        <!-- NSPDenne komponenterkomponent styreranvender selvNSP logningSecurity API -->
        <exclude-subsystems> <dependencies>
            <subsystem<module name="loggingdk.sds.nsp.security"/>
        </exclude-subsystems>
dependencies>
        <!-- Denne komponent anvender NSP Security API -->
        <dependencies>
            <module name="dk.sds.nsp.security"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

Det er vigtigt af forstå, at der ikke nødvendigvis er sammenhæng mellem det versionsnummer af NSP Security API, som bliver udtrykt i Maven afhængigheden, og den version af NSP Security API, der bliver stillet til rådighed af Wildfly.

</deployment>
</jboss-deployment-structure>

Det er vigtigt af forstå, at der ikke nødvendigvis er sammenhæng mellem det versionsnummer af NSP Security API, som bliver udtrykt i Maven afhængigheden, og den version af NSP Security API, der bliver stillet til rådighed af Wildfly.

Det er komponentens eget ansvar at sørge for, at der er sammenhæng mellem disse. Eventuelle versionsforskelle mellem det, som en komponent tror, at den får Det er komponentens eget ansvar at sørge for, at der er sammenhæng mellem disse. Eventuelle versionsforskelle mellem det, som en komponent tror, at den får stillet til rådighed, og det, som den rent faktisk får stillet til rådighed, kan give en masse udfordringer og underlige fejl (NoSuchMethodException, ClassNotFoundException med flere), når komponenten afvikles og anvender NSP Security API.

...

Disse tre punkter er beskrevet i de følgende afsnit

Understøttede brugertyper og dokumentation i Brugerhistorier

TODO: link til dokumentationskrav

, hvor der også vil være praktisk eksempler. Det er vigtigt at notere sig, at eksempler i denne anvenderguide er ment som inspiration til anvendere af NSP Security API.

Det er således ikke en udtømmende facitliste. Anvendelsen af NSP Security API kræver komponentspecifikke og forretningsspecifikke overvejelser:

  • Hvilke brugertyper er til stede i min komponent?
  • Hvordan skal disse brugertyper tjekkes/mappes i forhold til de forretningsregler, der gælder i min komponent?

Understøttede brugertyper og dokumentation i Brugerhistorier

En given NSP komponent skal forholde sig til, hvilke brugertyper den understøtter. Dette er i høj grad en forretningsmæssig beslutning, og det er vigtigt at en komponent dokumenterer de understøttede brugertyper. Dokumentationen af brugertyperne og de brugerhistorier, som de indgår i foretages i dokumenttypen Brugerhistorier. Et eksempel på et sådant dokument er En given NSP komponent skal forholde sig til, hvilke brugertyper den understøtter. Dette er i høj grad en forretningsmæssig beslutning, og det er vigtigt at en komponent dokumenterer de understøttede brugertyper. Dokumentationen af brugertyperne og de brugerhistorier, som de indgår i foretages i dokumenttypen Brugerhistorier. Et eksempel på et sådant dokument er DROS - Brugerhistorier. Mange eksisterende NSP komponenter har ikke dette dokument, men en succesfuld anvendelse af NSP Security API forudsætter, at det eksisterer. Derfor bør indførelsen af NSP Security API først ske efter, at denne dokumentation er udarbejdet. Denne dokumenttype er ikke et teknisk dokument og indholdet skal som minimum gennemlæses og verificeres af SDS NSP arkitekt og Product Owner.

Dokumentation af brugerhistorier er den forretningsrettede dokumentation af, hvad en komponent kan, og hvem der kan anvende den og er således også en forudsætning for at anvendere kan scope og designe deres integration i henhold til dokumentationen i Guide til Anvendere. Se f.eks. DROS - Guide til anvendere for et eksempel på at sammenholde anvenderguide og brugerhistorier.

TODO måske tilføje til design og arkitektur: Fremadrettet vil det give mening at ændringer til en NSP komponent udtrykkes som brugerhistorierSe i øvrigt Dokumentationskrav for NSP-platformen for at få et overblik over de dokumentationspakker, der bør være til stede i forbindelse med en NSP leverance.

Mapning fra NSP Security API til understøttede brugertyper og dokumentation i Design og Arkitektur

...

Brugertypen Borger (sundhed.dk)

VerifikationMapning til DDS ServiceActor
SecurityContextTicketAudienceVerificeres ikke - må gerne være der


ValidityEr valid

Message
Verificeres ikke - må gerne være der

ActingUserUserTypeMå ikke være der

PrincipalUserUserTypeMå ikke være der

OrganisationIdentifierFormatSkal være CVR


IdentifierSkal være der og skal være "niveau 3" whitelistet


NameVerificeres ikke - må gerne være der

Client
Verificeres ikke - må gerne være der

HSUID Header



Det verificeres, at HSUID headeren findes, og at den modellerer en borger.

NB. I praksis bør HSUID Headeren foldes ud, hvis den bruges, og anvendelsen af de enkelte egenskaber beskrives på samme måde som ovenstående egenskaber fra NSP Security API.

Brugertypen: Borger

PersonIdentifier

...

Implementation af validering og mapning af brugertyper

...

I det følgende gennemgås de enkelte trin (med et eksempel som forklaring).

Når kæden er tilendebragt, så er det op til komponenten at tjekke, om resultatet er tilfredsstillende: Understøtter vi f.eks. den pågældende Actor i den specifikke kontekst.

Eksempel Eksempel på Actormodellering:

NSP Eksempel Service kaldes af en ikke-autoriseret sundhedsfaglig med et bruger id-kort og en HSUID header som angiver, at man arbejder på vejne af en autoriseret læge.

...

  • Doctor
  • Nurse
  • NurseOnBehalfOfDoctor
  • HealthCareProfessional
  • ExecutiveHealthCareProfessional
  • HealthCareProfessionalOnBehalfOfDoctor
  • TrustedSystemUser

ActorProvider: Match af brugertyper

Dette trin opererer udelukkende på NSP Security API og forsøger udfra undersøgelse af NSP Security API modellen at matche til een af komponentens brugertyper. Dette kan med fordel laves som en række af match-metoder (en til hver brugertype) på en ActorProvider-klasse i komponenten. En ActorProvider kan bestemme en Actor, hvis en-og-kun-en af de implementerede match metoder returnere en Actor. I dette tilfælde sendes denne videre i algoritmen - ellers kastes en Exception.

I match-metoderne er det kun attributterne på modellen i NSP SecurityAPI (SecurityContext) som ligger til grund for valget af Actor og det er klart at nogle af disse vil ikke kunne matche med vores nuværende DGWS/IDWS billetter, men fremtidige vil kunne, derfor skal vi stadig have dem med. Implementationen skal matche det, der er dokumenteret i komponentens design og arkitekturdokumentation.

I NSP Security API findes der en DevelopmentSecurityProvider klasse, der vil kunne anvendes i udarbejdelse af unit tests for ActorProvider-klassen.

Eksempel på ActorProviders match-funktion:

I NSP Eksempl Service laves herefter en ActorProvider klasse der har en public Actor getActor(SecurityContext) metode som kalder følgende metoder:

private Actor matchDoctor(SecurityContext)

private Actor matchNurse(SecurityContext)

private Actor matchNurseOnBehalfOfDoctor(SecurityContext)

private Actor matchHealthCareProfessional(SecurityContext)

private Actor matchExecutiveHealthCareProfessional(SecurityContext)

private Actor matchHealthCareProfessionalOnBehalfOfDoctor(SecurityContext)

private Actor matchTrustedSystemUser(SecurityContext)

I det følgende vil vi give et eksempel i pseudokode på, hvordan matchDoctor og matchTrustedSystemUser vil kunne se ud:

I dette eksempel vil komponenten efter hele kæden er færdig stå med en Actor. Den sidste i listen, TrustedSystemUser, giver i sig selv ikke mening i komponenten, hvorfor den skal afvises. Denne aktør er kun med som en midlertidig type: Den opstår under ActorProvider men forventes transformeret til en faktisk type i ActorTransformer.

ActorProvider: Match af brugertyper

Dette trin opererer udelukkende på NSP Security API og forsøger udfra undersøgelse af NSP Security API modellen at matche til een af komponentens brugertyper. Dette kan med fordel laves som en række af match-metoder (en til hver brugertype) på en ActorProvider-klasse i komponenten. En ActorProvider kan bestemme en Actor, hvis en-og-kun-en af de implementerede match metoder returnere en Actor. I dette tilfælde sendes denne videre i algoritmen - ellers kastes en Exception.

I match-metoderne er det kun attributterne på modellen i NSP SecurityAPI (SecurityContext) som ligger til grund for valget af Actor og det er klart at nogle af disse vil ikke kunne matche med vores nuværende DGWS/IDWS billetter, men fremtidige vil kunne, derfor skal vi stadig have dem med. Implementationen skal matche det, der er dokumenteret i komponentens design og arkitekturdokumentation.

I NSP Security API findes der en DevelopmentSecurityProvider klasse, der vil kunne anvendes i udarbejdelse af unit tests for ActorProvider-klassen.

Eksempel på ActorProviders match-funktion:

I NSP Eksempl Service laves herefter en ActorProvider klasse der har en public Actor getActor(SecurityContext) metode som kalder følgende metoder:

private Actor matchDoctor(SecurityContext)

private Actor matchNurse(SecurityContext)

private Actor matchNurseOnBehalfOfDoctor(SecurityContext)

private Actor matchHealthCareProfessional(SecurityContext)

private Actor matchExecutiveHealthCareProfessional(SecurityContext)

private Actor matchHealthCareProfessionalOnBehalfOfDoctor(SecurityContext)

private Actor matchTrustedSystemUser(SecurityContext)


I det følgende vil vi give et eksempel i pseudokode på, hvordan matchDoctor og matchTrustedSystemUser vil kunne se ud:

Code Block
public Actor getActor(SecurityContext sc) throws SecurityException {
	if (sc.getTicket.isValid()) {
		throw new SecurityException("Sikkerhedsbilletten er ikke valid");
	}

	Actor doctor = matchDoctor(sc);
	Actor nurse = matchNurse(sc);
	Actor nurseOnBehalfOf = matchNurseOnBehalfOfDoctor(sc);
	Actor healthCareProfessional = matchHealthCareProfessional(sc);
 	Actor executiveHealthCareProfessional = matchExecutiveHealthCareProfessional(sc);
 	Actor healthCareProfessionalOnBehalfOfDoctor = matchHealthCareProfessionalOnBehalfOfDoctor(sc);
	Actor trustedSystemUser = matchTrustedSystemUser(sc);

	Actor actor = checkExactlyOneActorHasBeenDetemined(doctor, nurse, nurseOnBehalfOf, executiveHealthCareProfessional, healthCareProfessionalOnBehalfOfDoctor, trustedSystemUser);
	return actor;
}

private checkExactlyOneActorHasBeenDetemined(Actor determined...) throws SecurityException {
	// Tjekker, at der er præcist een ellers smides exception
}

private Actor matchDoctor(SecurityContext sc) {

	// Tjekker om nødvendige bruger og organisation findes. Der må ikke være en på-vegne-af-bruger i for denne aktør
	if (!sc.getActingUser().isPresent() || sc.getResponsibleUser().isPresent() || !sc.getOrganisation().isPresent()) {
		return null;
	}

	// Matcher brugertypen
	if (!sc.getActingUser().get().getUserType() != UserType.HealthcareProfessional) {
		return null;
 	}

	// Matcher identifier typen
 	if (!sc.getActingUser().get().getUserType().equals(UserType.HealthcareProfessional)) {
		return null;
 	}
 
	// Tjekker, at der er tale om en CPR identifier på brugeren
    ....
	// Tjek, at der findes en autorisationskode
    ....
	// Tjekker, at der findes en uddannelseskode og at den er af typen '7071' dvs læge
    ....
 
    return new DoctorActor(sc.getActingUser().get().getIdentifier(), sc.getActingUser().get().getCredentials().get().getAuthorizationCode().get());
}

private Actor matchTrustedSystemUser(SecurityContext sc) {

 	// Der må ikke være brugere tilstede på security context
	if (sc.getActingUser().isPresent() || sc.getResponsibleUser().isPresent()) {
		return null;
	}
 
	// Tjek, at der findes en organisation og at identifier typen for denne er CVR
    ....
	
    return new TrustedSystemUser(sc.getOrganisation().get().getIdentifier());
}

ActorTransformer: Transformerer en brugertype til en anden

Efter den umiddelbare matching af brugertyper i ActorProvider er der eksempler på, at en brugertype kan blive til en anden, hvis de rette omstændigheder er tilstede. I mange NSP services er det muligt at angive en mere detaljeret kontekst i en HSUID header. Dette kan implementeres i en ActorTransformer klasse, der kan tage andet kontekst end SecurityContexten, som vi var begrænset til i ActorProvideren.

Eksempel på ActorTransformer:

I vores eksempel er der således mulighed for, at en TrustedSystemUser kan blive til en anden brugertype udfra oplysninger i HSUID.

Code Block
public Actor transformActor(Actor actor, ValidatedHsuidAttributes hsuid) throws SecurityException {

	if (actor.isTrustedSystemUser()) {

		// Tjek, at den trustede bruger har et CVR nummer, der er godkendt
		if (isTrusted(((TrustedSystemUser) actor).getCVR()))) {
		 	throw new SecurityException("CVR nummeret er ikke trustet");
		}

		// Hsuid skal angive
Code Block
public Actor getActor(SecurityContext sc) {
	if (sc.getTicket.isValid()) {
		throw new SecurityException("Sikkerhedsbilletten er ikke valid");
	}

	Actor doctor = matchDoctor(sc);
	Actor nurse = matchNurse(sc);
	Actor nurseOnBehalfOf = matchNurseOnBehalfOfDoctor(sc);
	Actor healthCareProfessional = matchHealthCareProfessional(sc);
 	Actor executiveHealthCareProfessional = matchExecutiveHealthCareProfessional(sc);
 	Actor healthCareProfessionalOnBehalfOfDoctor = matchHealthCareProfessionalOnBehalfOfDoctor(sc);
	Actor trustedSystemUser = matchTrustedSystemUser(sc);

	Actor actor = checkExactlyOneActorHasBeenDetemined(doctor, nurse, nurseOnBehalfOf, executiveHealthCareProfessional, healthCareProfessionalOnBehalfOfDoctor, trustedSystemUser);
	return actor;
}

private checkExactlyOneActorHasBeenDetemined(Actor determined...) throws SecurityException {
	// Tjekker, at der er præcist een ellers smides exception
}

private Actor matchDoctor(SecurityContext sc) {

	// Tjekker om nødvendige bruger og organisation findes. Der må ikke være en på-vegne-af-bruger i for denne aktør
	if (!sc.getActingUser().isPresent() || sc.getResponsibleUser().isPresent() || !sc.getOrganisation().isPresent()) {
		return null;
	}

	// Matcher brugertypen
	if (!sc.getActingUser().get().getUserType() != UserType.HealthcareProfessional) {
		return null;
 	}

	// Matcher identifier typen
 	if (!sc.getActingUser().get().getUserType().equals(UserType.HealthcareProfessional)) {
		return null;
 	}
 
	// Tjekker, at der er tale om en CPRsundhedsprofessionelbruger identifierfor at brugeren
transformation kan foregå
		if  ....
	// Tjek, at der findes en autorisationskode
    ....
(hsuid.isHealthCareProfessional()) {
			ValidatedHealthcareProfessionalHsuidAttributes healthcareProfHsuid = hsuid.getValidatedHealthcareProfessionalHsuidAttributes();
			String autorisationsId = validatedHealthcareProfessionalHsuidAttributes.getUserAuthorizationCode();
			String uddannelsesKode = verifyAutorisationsIdAndLookupUddannelsesKode(autorisationsId);
			// Tjekker, at deruddannelseskode findes en uddannelseskode og atidentificerer den er af typen '7071' dvs læge
    .en doktor			
			...
 
    return new DoctorActor(sc.getActingUser().get().getIdentifier(), sc.getActingUser().get().getCredentials().get().getAuthorizationCode().get());
}

private Actor matchTrustedSystemUser(SecurityContext sc) {

 	// Der må ikke være brugere tilstede på security context
	if (sc.getActingUser().isPresent() || sc.getResponsibleUser().isPresent()) {
		return null;
	}
 
	// Tjek, at der findes en organisation og at identifier typen for denne er CVR
    ....
	
    return new TrustedSystemUser(sc.getOrganisation().get().getIdentifier());
}

TODO kode eksempel fra DDS (måske pseudokode for at hjælpe)?

			// Tjekker om der er tale på vegne af
			if (healthcareProfHsuid.getResponsibleUserCivilRegistrationNumber() != null) {
				// Nu blev vi lige sundhedsfaglig på vegne af læge
				return new HealthCareProfessionalOnBehalfOfDoctor(healthcareProfHsuid.getActingUserCivilRegistrationNumber(),
								healthcareProfHsuid.getResponsibleUserCivilRegistrationNumber(), autorisationsId);
			} else {
				// Nu blev vi læge
				return new DoctorActor(healthcareProfHsuid.getActingUserCivilRegistrationNumber(), autorisationsId);
			}
		}
	}

	return actor;
}

ActorEnricher: Tilføjer information til Actor

Det sidste led i kæder er medtaget for at kunne berige Actoren med yderligere information. F.eks. en SOR kode fra HSUID header, eller patient-kontekst fra requestet.

Dette kan implementeres i en klasse ActorEnricher i en metode f.eks. public Actor enrichActor(Actor actor, HSUID hsuid).TODO Hvordan beskrive brugertyper og sikkerhedsprotokoller for anvenderne?