Hvordan komme i gang
Klienten er tilgjengelig som en NuGet-pakke. Denne vil oppdateres jevnlig etter hvert som ny funksjonalitet legges til.
For å installere NuGet-pakken, gjør følgende i Visual Studio/Rider:
- Velg TOOLS -> NuGet Package Manager -> Manage Nuget Packages for Solution…
- Søk etter Difi.SikkerDigitalPost.Klient. Flere pakker vil dukke opp. Installer de som er relevant for deg. Pass på å IKKE installer
difi-sikker-digital-post-klient
pakken. Den er ett .NET Framework bibliotek med uheldig likt navn. Hvis du leter etter .NET Framework dokumentasjonen, se versjon 2.- Ønsker du pre-release, må du sørge for at det står Include Prerelease i drop-down menyen rett over søkeresuløtatene (der det står Stable Only).
- Velg Difi.SikkerDigitalPost.Klient.X og trykk Install.
Installer og bruk databehandlersertifikat
Som bruker av dette biblioteket er du en Databehandler som har ansvar for sending av meldinger. For å gjøre dette trenger du et sertifikat for å kunne autentisere deg mot Meldingsformidleren. Du kan lese mer om aktørene hos begrep.difi.no. Dette bør installeres på maskinen som skal bruke klientbiblioteket. Grunnen til at vi ønsker å installere det er for å ikke ha passord i klartekst i koden.
SSL Certificates are small data files that digitally bind a cryptographic key to an organization's details. When installed on a web server, it activates the padlock and the https protocol (over port 443) and allows secure connections from a web server to a browser.
For å kommunisere over HTTPS trenger du å signere dine requests med ett databehandlersertifikat. Dette sertifikatet kan lastes direkte fra en fil eller fra Windows Certificate Store.
Følgende steg vil installere sertifikatet i din Certificate Store. Dette burde gjøres på serveren hvor din applikasjon skal kjøre.
For mer informasjon, se Microsoft Dokumentasjonen.
Filplasseringen og passord til sertifikatet må legges ett trygt sted.
Filplassering i Windows er:
%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
Filplassering i MacOS/Linux er:
~/.microsoft/usersecrets/<user_secrets_id>/secrets.json
Legg til følgende UserSecretsId
element i din .csproj
fil:
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<UserSecretsId>enterprise-certificate</UserSecretsId>
</PropertyGroup>
Dette betyr at elementet <user_secrets_id>
in the filplasseringen vil være enterprise-certificate
.
Fra command linjen, naviger til filplassering hvor din hoved .csproj
fil ligger og kjør følgene kommandoer med dine egne sertifikat verdier:
dotnet user-secrets set "Certificate:Path:Absolute" "<your-certificate.p12>"
dotnet user-secrets set "Certificate:Password" "<your-certificate-password>"
Stol på sertifikatet i Windows:
- Dobbeltklikk på sertifikatet (Sertifikatnavn.p12)
- Velg at sertifikatet skal lagres i
Current User
ellerLocal Machine
og trykk Next If you are running the client library from a system account, but debugging from a different user, please install it onLocal Machine
, as this enables loading it from any user. - Filnavn skal nå være utfylt. Trykk Next
- Skriv inn passord for privatnøkkel og velg Mark this key as exportable …, trykk Next
- Velg Automatically select the certificate store based on the type of certificate
- Klikk Next og Finish
- Får du spørsmål om å godta sertifikatkjeden så du gjør det.
- Du skal da få en dialog som sier at importeringen var vellykket. Trykk OK.
Stol på sertifikatet i MacOS:
- Åpne
Keychain Access
- Velg
login
keychain - Trykk på File og deretter Import
- Velg databehandlersertifikatet og legg den til
Stol på sertifikatet i Linux:
Last ned root og intermediate sertifikatene fra Difi for din databehandlersertifkat utgiver.
Merk navnendringen til å ha .crt
på slutten for update-ca-certificates
:
sudo cp Buypass_Class_3_Test4_Root_CA.pem /usr/local/share/ca-certificates/Buypass_Class_3_Test4_Root_CA.crt
sudo cp Buypass_Class_3_Test4_CA_3.pem /usr/local/share/ca-certificates/Buypass_Class_3_Test4_CA_3.crt
sudo update-ca-certificates
Sende post
Det anbefales å bruke dokumentasjon i klassene for mer detaljert beskrivelse av inputparametere.
PostInfo for digital post
Først, lag en motaker av type DigitalPostMottaker
:
Postkassetjenesteleverandørene har ulik behandling av ikke-sensitiv tittel. Se begrep.difi.no for detaljer om denne forskjellen.
var personnummer = "01013300002";
var postkasseadresse = "ola.nordmann#2233";
var mottakersertifikat = new X509Certificate2(); //sertifikat hentet fra Oppslagstjenesten
var orgnummerPostkasse = new Organisasjonsnummer("123456789");
var mottaker = new DigitalPostMottaker(
personnummer,
postkasseadresse,
mottakersertifikat,
orgnummerPostkasse
);
var ikkeSensitivTittel = "En tittel som ikke er sensitiv";
var sikkerhetsnivå = Sikkerhetsnivå.Nivå3;
var postInfo = new DigitalPostInfo(mottaker, ikkeSensitivTittel, sikkerhetsnivå);
Husk at
OrgnummerPostkasse
er organisasjonsnummer til leverandør av postkassetjenesten. Organisasjonsnummeret leveres fra oppslagstjenesten sammen med postkasseadressen og sertifikatet til innbygger.
PostInfo for fysisk post
Skal du sende fysisk post må du først lage en FysiskPostMottaker
, en FysiskPostReturMottaker
og sette informasjon om farge og makulering:
var navn = "Ola Nordmann";
var adresse = new NorskAdresse("0001", "Oslo");
var mottakersertifikat = new X509Certificate2(); // sertifikat hentet fra Oppslagstjenesten
var orgnummerPostkasse = new Organisasjonsnummer("123456789");
var mottaker = new FysiskPostMottaker(navn, adresse, mottakersertifikat, orgnummerPostkasse);
var returMottaker = new FysiskPostReturmottaker(
"John Doe",
new NorskAdresse("0566", "Oslo")
{
Adresselinje1 = "Returgata 22"
});
var postInfo = new FysiskPostInfo(
mottaker,
Posttype.A,
Utskriftsfarge.SortHvitt,
Posthåndtering.MakuleringMedMelding,
returMottaker
);
Her er adressen av type NorskAdresse
eller UtenlandskAdresse
.
Ved sending av fysisk post må man oppgi en returadresse, uavhengig av om brevet er satt til Posthåndtering.MakuleringMedMelding
. Oppretting av en FysiskPostInfo vil da se slik ut:
Oppsett før sending
Opprett en avsender og en databehandler:
var orgnummerAvsender = new Organisasjonsnummer("123456789");
var avsender = new Avsender(orgnummerAvsender);
var orgnummerDatabehandler = new Organisasjonsnummer("987654321");
var avsendersertifikat = new X509Certificate2();
var databehandler = new Databehandler(orgnummerDatabehandler, avsendersertifikat);
Hvis man har flere avdelinger innenfor samme organisasjonsnummer, har disse fått unike avsenderidentifikatorer, og kan settes på følgende måte:
avsender.Avsenderidentifikator = "Avsenderidentifikator.I.Organisasjon";
Opprette forsendelse
Deretterer kan du opprette forsendelse. Forsendelsen inneholder de dokumentene som skal til mottakeren:
var hoveddokument = new Dokument(
tittel: "Dokumenttittel",
dokumentsti: "/Dokumenter/Hoveddokument.pdf",
mimeType: "application/pdf",
språkkode: "NO",
filnavn: "filnavn"
);
var dokumentpakke = new Dokumentpakke(hoveddokument);
var vedleggssti = "/Dokumenter/Vedlegg.pdf";
var vedlegg = new Dokument(
tittel: "tittel",
dokumentsti: vedleggssti,
mimeType: "application/pdf",
språkkode: "NO",
filnavn: "filnavn");
dokumentpakke.LeggTilVedlegg(vedlegg);
Avsender avsender = null; //Som initiert tidligere
PostInfo postInfo = null; //Som initiert tidligere
var forsendelse = new Forsendelse(avsender, postInfo, dokumentpakke);
Opprette forsendelse med Utvidelser
Difi har egne dokumenttyper, eller utvidelser, som kan sendes som metadata til hoveddokumenter. Disse utvidelsene er strukturerte xml-dokumenter med egne mime-typer.
Disse utvidelsene benyttes av postkasseleverandørene til å gi en øket brukeropplevelse for innbyggere.
Les mer om utvidelser på: https://difi.github.io/felleslosninger/sdp_utvidelser_index.html
var hoveddokument = new Dokument(
tittel: "Dokumenttittel",
dokumentsti: "/Dokumenter/Hoveddokument.pdf",
mimeType: "application/pdf",
språkkode: "NO",
filnavn: "filnavn"
);
var dokumentpakke = new Dokumentpakke(hoveddokument);
var vedleggssti = "/Dokumenter/Vedlegg.pdf";
var vedlegg = new Dokument(
tittel: "tittel",
dokumentsti: vedleggssti,
mimeType: "application/pdf",
språkkode: "NO",
filnavn: "filnavn"
);
dokumentpakke.LeggTilVedlegg(vedlegg);
var raw = "<?xml version=\"1.0\" encoding=\"utf-8\"?><lenke xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://begrep.difi.no/sdp/utvidelser/lenke\"><url>https://www.test.no</url><beskrivelse lang=\"nb\">This was raw string</beskrivelse></lenke>";
MetadataDocument metadataDocument = new MetadataDocument("lenke.xml", "application/vnd.difi.dpi.lenke", raw);
Avsender avsender = null; //Som initiert tidligere
PostInfo postInfo = null; //Som initiert tidligere
var forsendelse = new Forsendelse(avsender, postInfo, dokumentpakke) { MetadataDocument = metadataDocument };
Opprette klient og sende post
Siste steg er å opprette en SikkerDigitalPostKlient
:
var klientKonfig = new Klientkonfigurasjon(Miljø.FunksjoneltTestmiljø);
Databehandler databehandler = null; //Som initiert tidligere
Forsendelse forsendelse = null; //Som initiert tidligere
var sdpKlient = new SikkerDigitalPostKlient(databehandler, klientKonfig);
var transportkvittering = sdpKlient.Send(forsendelse);
if (transportkvittering is TransportOkKvittering)
{
//Når alt går fint
}
else if(transportkvittering is TransportFeiletKvittering)
{
var beskrivelse = ((TransportFeiletKvittering)transportkvittering).Beskrivelse;
}
Transportkvitteringen får du tilbake umiddelbart; den trenger du ikke å polle for å få.
Hente kvitteringer
For å hente kvitteringer må du sende en kvitteringsforespørsel:
var køId = "MpcId";
var kvitteringsForespørsel = new Kvitteringsforespørsel(Prioritet.Prioritert, køId);
Console.WriteLine(" > Henter kvittering på kø '{0}'...", kvitteringsForespørsel.Mpc);
Kvittering kvittering = sdpKlient.HentKvittering(kvitteringsForespørsel);
if (kvittering is TomKøKvittering)
{
Console.WriteLine(" - Kø '{0}' er tom. Stopper å hente meldinger. ", kvitteringsForespørsel.Mpc);
}
if (kvittering is TransportFeiletKvittering)
{
var feil = ((TransportFeiletKvittering) kvittering).Beskrivelse;
Console.WriteLine("En feil skjedde under transport.");
}
if (kvittering is Leveringskvittering)
{
Console.WriteLine(" - En leveringskvittering ble hentet!");
}
if (kvittering is Åpningskvittering)
{
Console.WriteLine(" - Har du sett. Noen har åpnet et brev. Moro.");
}
if (kvittering is Returpostkvittering)
{
Console.WriteLine(" - Du har fått en returpostkvittering for fysisk post.");
}
if (kvittering is Mottakskvittering)
{
Console.WriteLine(" - Kvittering på sending av fysisk post mottatt.");
}
if (kvittering is Feilmelding)
{
var feil = (Feilmelding)kvittering;
Console.WriteLine(" - En feilmelding ble hentet :" + feil.Detaljer, true);
}
Husk at det ikke er mulig å hente nye kvitteringer før du har bekreftet mottak av nåværende.
sdpKlient.Bekreft((Forretningskvittering)kvittering);
Kvitteringer du mottar når du gjør en kvitteringsforespørsel kan være av følgende typer: Leveringskvittering
,Åpningskvittering
, Returpostkvittering
, Mottakskvittering
eller Feilmelding
. Kvittering kan også være av typenTransportFeiletKvittering
. Dette kan skje når selve kvitteringsforespørselen er feilformatert.
Husk at hvis du får
TomKøKvittering
så er køen tom. Du henter bare kvitteringer fra kø gitt avMpcId
ogPrioritet
. Hvis ikke dette blir satt spesifikt vil det hentes fra kø hvorMpcId = ""
ogPrioritet = Prioritet.Normal
.
Logging
Debugging
Sette opp logging
Klient biblioteket har evnen til å logge nyttig informasjon som kan bli brukt for debugging.
For å skru på logging, gi SikkerDigitalPostKlient
en Microsoft.Extensions.Logging.ILoggerFactory
i konstruktøren.
Dette er Microsoft sitt eget logging API og lar brukeren velge deres egen logging framework.
Om du skrur på logging med nivå DEBUG
vil output være positive resultater av requests og verre, WARN
gir bare feilet requests eller verre, mens ERROR
gir bare feilet requests.
Disse loggerne vil være under Difi.SikkerDigitalPost.Klient
namespace.
Implementing using NLog
Det er flere måter å implementere en logger, men følgene eksempler vil være basert på NLog dokumentasjonen.
- Installer Nuget pakkene
NLog
,NLog.Extensions.Logging
ogMicrosoft.Extensions.DependencyInjection
. - Legg en
nlog.config
fil. Den følgende er ett eksempel som logger til både fil og konsol:
I din applikasjon, gjør følgende for å lage en logger og gi den til SikkerDigitalPostKlient
:
private static IServiceProvider CreateServiceProviderAndSetUpLogging()
{
var services = new ServiceCollection();
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging((builder) => builder.SetMinimumLevel(LogLevel.Trace));
var serviceProvider = services.BuildServiceProvider();
SetUpLoggingForTesting(serviceProvider);
return serviceProvider;
}
private static void SetUpLoggingForTesting(IServiceProvider serviceProvider)
{
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
loggerFactory.AddNLog(new NLogProviderOptions {CaptureMessageTemplates = true, CaptureMessageProperties = true});
NLog.LogManager.LoadConfiguration("./nlog.config");
}
static void Main(string[] args)
{
//Oppsett beskrevet tidligere:
Klientkonfigurasjon klientKonfig = null;
DataBehandler dataBehandler = null;
var serviceProvider = CreateServiceProviderAndSetUpLogging();
var client = new SikkerDigitalPostKlient(dataBehandler, klientKonfig, serviceProvider.GetService<ILoggerFactory>());
}
Request og Response Logging
Til integrasjon og debugging formål så kan det være nyttig å logge direkte requests og responses som kommer “over the wire”. Dette kan oppnåes ved å gjøre følgende:
Sett denne property Klientkonfigurasjon.LoggForespørselOgRespons = true
.
Advarsel: Man skal aldri skru på request logging i ett produksjonsmiljø. Det vil ha en sterk negativ virkning på ytelse.
Prosessere dokumentpakke som sendes
Når man logger forespørsel og respons, så logges bare XML som sendes, ikke selve dokumentpakken. Det er to måter å logge denne på:
- Aktiver logging til disk vha
Klientkonfigurasjon.AktiverLagringAvDokumentpakkeTilDisk
. - Implementer
IDokumentPakkeProsessor
og legg til iKlientkonfigurasjon.Dokumentpakkeprosessorer
Ytelse
Klientbiblioteket benytter en HttpWebRequest
for å kommunisere med Meldingsformidleren. I en konsollapplikasjon er denne begrenset til maks to samtidige forbindelser om gangen, mens den i en asp.net applikasjon er begrenset til ti. Dersom du ønsker å sende flere brev samtidig kan denne verdien endres f.eks til 3. Mer enn dette anbefales ikke.
System.Net.ServicePointManager.DefaultConnectionLimit = 3;
Se ServicePointManager.DefaultConnectionLimit for mer informasjon.
Klassen SikkerDigitalPostKlient
fungerer best ved at man oppretter en instans per applikasjon. SikkerDigitalPostKlient
bruker en og samme instans av HttpClient under panseret. Denne klassen er trådsikker og beste måte å bruke denne klassen på er å ha en instans per applikasjon som gjenbrukes for alle http-kall i applikasjons levetid. Av trådsikkerhetshensyn og ytelse er dette også måten brukere av biblioteket bør benytte SikkerDigitalPostKlient
på.