diff --git a/README.md b/README.md index 566c931..4c63f32 100644 --- a/README.md +++ b/README.md @@ -36,16 +36,42 @@ The algorithm, which performs the validation of the Web eID authentication token In case you need to provide your own CA certificates, add the `.cer` files to the `src/WebEid.AspNetCore.Example/Certificates/{Dev,Prod}` profile-specific directory. ### 3. Setup the `libdigidocpp` library for signing + `libdigidocpp` is a library for creating, signing and verifying digitally signed documents according to XAdES and XML-DSIG standards. It is a C++ library that has [SWIG](http://swig.org/) bindings for C#. Set up the `libdigidocpp` library as follows: -1. Install the _libdigidocpp-3.14.4.msi_ package or higher. The installation packages are available from [https://github.com/open-eid/libdigidocpp/releases](https://github.com/open-eid/libdigidocpp/releases). +#### For MS Windows + +1. Install the _libdigidocpp-3.17.1.msi_ package or higher. The installation packages are available from [https://github.com/open-eid/libdigidocpp/releases](https://github.com/open-eid/libdigidocpp/releases). 2. Copy the C# source files from the `libdigidocpp` installation folder `include\digidocpp_csharp` to the `src\WebEid.AspNetCore.Example\DigiDoc` folder. 3. Copy all files from either the `x64` subfolder of the `libdigidocpp` installation folder to the example application build output folder `bin\...\net60` (after building, see next step). When building custom applications, choose `x64` if your application is 64-bit and `x86` if it is 32-bit. 4. When running in the `Development` profile, create an empty file named `EE_T.xml` for TSL cache as described in the [_Using test TSL lists_](https://github.com/open-eid/libdigidocpp/wiki/Using-test-TSL-lists#preconditions) section of the `libdigidocpp` wiki. -Further information is available in the [libdigidocpp example C# application](https://github.com/open-eid/libdigidocpp/tree/master/examples/DigiDocCSharp) and in the [`libdigidocpp` wiki](https://github.com/open-eid/libdigidocpp/wiki). +#### For Ubuntu Linux + +1. Add RIA repository to install the official _libdigidocpp-csharp_ package: +```sh +wget https://github.com/web-eid/web-eid-asp-dotnet-example/raw/main/src/ria_public_key.gpg +cp ria_public_key.gpg /usr/share/keyrings/ria-repository.gpg +echo "deb [signed-by=/usr/share/keyrings/ria-repository.gpg] https://installer.id.ee/media/ubuntu/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/ria-repository.list +``` +2. Install the _libdigidocpp-csharp_ package: +```sh +apt update +apt install -y --no-install-recommends libdigidocpp-csharp +``` + +#### For macOS + +1. Install the _libdigidocpp-3.17.1.pkg_ package or higher. The installation packages are available from [https://github.com/open-eid/libdigidocpp/releases](https://github.com/open-eid/libdigidocpp/releases). +2. Copy the C# source files from `/Library/libdigidocpp/include/digidocpp_csharp` directory to `src/WebEid.AspNetCore.Example/DigiDoc` directory. +3. Go to `src/WebEid.AspNetCore.Example/bin/.../net60` directory and create symbolic link to `/Library/libdigidocpp/lib/libdigidoc_csharp.dylib` library: +```cmd +ln -s /Library/libdigidocpp/lib/libdigidoc_csharp.dylib +``` + +Further information is available in the [libdigidocpp example C# application source code](https://github.com/open-eid/libdigidocpp/tree/master/examples/DigiDocCSharp) and in the [`libdigidocpp` Wiki](https://github.com/open-eid/libdigidocpp/wiki). ### 4. Build the application @@ -60,7 +86,7 @@ dotnet build If you have a test eID card, use the `Development` profile. In this case access to paid services is not required, but you need to upload the authentication and signing certificates of the test card to the test OCSP responder database as described in section _[Using DigiDoc4j in test mode with the `dev` profile](https://github.com/web-eid/web-eid-spring-boot-example#using-digidoc4j-in-test-mode-with-the-dev-profile)_ of the Web eID Java example application documentation. The`Development` profile is activated by default. -If you only have a production eID card, use the `Production` profile. You can still test authentication without further configuration; however, for digital signing to work, you need access to a paid timestamping service as described in section [_Using DigiDoc4j in production mode with the `prod` profile_](https://github.com/web-eid/web-eid-spring-boot-example#using-digidoc4j-in-production-mode-with-the-prod-profile) of the Web eID Java example documentation. +If you only have a production eID card, i.e. an eID card issued to a real person or organization, use the `Production` profile. You can still test authentication without further configuration; however, for digital signing to work, you need access to a paid timestamping service as described in section [_Using DigiDoc4j in production mode with the `prod` profile_](https://github.com/web-eid/web-eid-spring-boot-example#using-digidoc4j-in-production-mode-with-the-prod-profile) of the Web eID Java example documentation. You can specify the profile as an environment variable `ASPNETCORE_ENVIRONMENT` when running the application. To set the profile for the current session before starting the app using [`dotnet run`](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-run), use the following command: ```cmd @@ -193,5 +219,4 @@ app.UseForwardedHeaders(new ForwardedHeadersOptions By default, this middleware is already enabled in the application. -A Docker Compose configuration file `docker-compose.yml` is available in the `src` directory for running the Docker image `web-eid-asp-dotnet-example` on port 8480 behind a reverse proxy. - +A Docker Compose configuration file `docker-compose.yml` is available in the `src` directory for running the Docker image `web-eid-asp-dotnet-example` on port 8480 behind a reverse proxy. \ No newline at end of file diff --git a/src/WebEid.AspNetCore.Example/Controllers/Api/AuthController.cs b/src/WebEid.AspNetCore.Example/Controllers/Api/AuthController.cs index c4874d4..b8873fd 100644 --- a/src/WebEid.AspNetCore.Example/Controllers/Api/AuthController.cs +++ b/src/WebEid.AspNetCore.Example/Controllers/Api/AuthController.cs @@ -17,7 +17,7 @@ // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -namespace WebEid.AspNetCore.Example.Controllers.Api +namespace WebEid.AspNetCore.Example.Controllers.Api { using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; @@ -29,6 +29,7 @@ using System.Threading.Tasks; using Security.Challenge; using WebEid.AspNetCore.Example.Dto; + using System; [Route("[controller]")] [ApiController] @@ -48,12 +49,13 @@ public AuthController(IAuthTokenValidator authTokenValidator, IChallengeNonceSto public async Task Login([FromBody] AuthenticateRequestDto authToken) { var certificate = await this.authTokenValidator.Validate(authToken.AuthToken, this.challengeNonceStore.GetAndRemove().Base64EncodedNonce); - var claims = new List - { - new Claim(ClaimTypes.GivenName, certificate.GetSubjectGivenName()), - new Claim(ClaimTypes.Surname, certificate.GetSubjectSurname()), - new Claim(ClaimTypes.NameIdentifier, certificate.GetSubjectIdCode()) - }; + + List claims = new(); + + AddNewClaimIfCertificateHasData(claims, ClaimTypes.GivenName, certificate.GetSubjectGivenName); + AddNewClaimIfCertificateHasData(claims, ClaimTypes.Surname, certificate.GetSubjectSurname); + AddNewClaimIfCertificateHasData(claims, ClaimTypes.NameIdentifier, certificate.GetSubjectIdCode); + AddNewClaimIfCertificateHasData(claims, ClaimTypes.Name, certificate.GetSubjectCn); var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); @@ -77,8 +79,16 @@ await HttpContext.SignInAsync( public async Task Logout() { RemoveUserContainerFile(); - await HttpContext.SignOutAsync( - CookieAuthenticationDefaults.AuthenticationScheme); + await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + } + + private static void AddNewClaimIfCertificateHasData(List claims, string claimType, Func dataGetter) + { + var claimData = dataGetter(); + if (!string.IsNullOrEmpty(claimData)) + { + claims.Add(new Claim(claimType, claimData)); + } } } } diff --git a/src/WebEid.AspNetCore.Example/Pages/Welcome.cshtml.cs b/src/WebEid.AspNetCore.Example/Pages/Welcome.cshtml.cs index fcd2c03..7e19ee1 100644 --- a/src/WebEid.AspNetCore.Example/Pages/Welcome.cshtml.cs +++ b/src/WebEid.AspNetCore.Example/Pages/Welcome.cshtml.cs @@ -35,7 +35,17 @@ private static string GetPrincipalName(ClaimsIdentity identity) var surname = identity.Claims.Where(claim => claim.Type == ClaimTypes.Surname) .Select(claim => claim.Value) .SingleOrDefault(); - return $"{givenName} {surname}"; + + if (!string.IsNullOrEmpty(givenName) && !string.IsNullOrEmpty(surname)) + { + return $"{givenName} {surname}"; + } + else + { + return identity.Claims.Where(claim => claim.Type == ClaimTypes.Name) + .Select(claim => claim.Value) + .SingleOrDefault(); + } } } } \ No newline at end of file diff --git a/src/WebEid.AspNetCore.Example/Properties/launchSettings.json b/src/WebEid.AspNetCore.Example/Properties/launchSettings.json index a2e5ff7..1532817 100644 --- a/src/WebEid.AspNetCore.Example/Properties/launchSettings.json +++ b/src/WebEid.AspNetCore.Example/Properties/launchSettings.json @@ -8,6 +8,15 @@ } }, "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:44391", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true,