Skip to content

Commit 821383b

Browse files
NFC-99 Web eID for Mobile authentication support for web-eid example
Signed-off-by: Sander Kondratjev <[email protected]>
1 parent 1f78e15 commit 821383b

19 files changed

+837
-109
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (c) 2021-2024 Estonian Information System Authority
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
// this software and associated documentation files (the "Software"), to deal in
5+
// the Software without restriction, including without limitation the rights to
6+
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7+
// the Software, and to permit persons to whom the Software is furnished to do so,
8+
// subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all
11+
// copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15+
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
namespace WebEid.AspNetCore.Example.Controllers.Api
21+
{
22+
using System;
23+
using System.Text;
24+
using Microsoft.AspNetCore.Mvc;
25+
using Microsoft.Extensions.Options;
26+
using System.Text.Json;
27+
using System.Text.Json.Serialization;
28+
using WebEid.AspNetCore.Example.Options;
29+
using WebEid.Security.Challenge;
30+
31+
[ApiController]
32+
[Route("auth/mobile")]
33+
public class MobileAuthController : ControllerBase
34+
{
35+
private const string WebEidMobileAuthPath = "auth";
36+
private const string MobileLoginPath = "/auth/mobile/login";
37+
38+
private readonly IChallengeNonceGenerator nonceGenerator;
39+
private readonly WebEidMobileOptions mobileOptions;
40+
41+
public MobileAuthController(
42+
IChallengeNonceGenerator nonceGenerator,
43+
IOptions<WebEidMobileOptions> mobileOptions)
44+
{
45+
this.nonceGenerator = nonceGenerator;
46+
this.mobileOptions = mobileOptions.Value;
47+
}
48+
49+
[HttpPost("init")]
50+
public IActionResult Init()
51+
{
52+
var challenge = nonceGenerator.GenerateAndStoreNonce(TimeSpan.FromMinutes(5));
53+
var challengeBase64 = challenge.Base64EncodedNonce;
54+
55+
var loginUri = $"{Request.Scheme}://{Request.Host}{MobileLoginPath}";
56+
57+
var payload = new AuthPayload(
58+
challengeBase64,
59+
loginUri,
60+
mobileOptions.RequestSigningCert ? true : null
61+
);
62+
63+
var json = JsonSerializer.Serialize(payload);
64+
var encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(json));
65+
66+
var authUri = BuildAuthUri(encodedPayload);
67+
68+
return Ok(new AuthUri(authUri));
69+
}
70+
71+
private string BuildAuthUri(string encodedPayload)
72+
{
73+
var baseUri = mobileOptions.BaseRequestUri;
74+
75+
if (baseUri.StartsWith("http", StringComparison.OrdinalIgnoreCase))
76+
{
77+
return $"{baseUri.TrimEnd('/')}/{WebEidMobileAuthPath}#{encodedPayload}";
78+
}
79+
80+
return $"{baseUri}{WebEidMobileAuthPath}#{encodedPayload}";
81+
}
82+
83+
public record AuthPayload(
84+
[property: JsonPropertyName("challenge")] string Challenge,
85+
[property: JsonPropertyName("login_uri")] string LoginUri,
86+
[property: JsonPropertyName("get_signing_certificate")] bool? GetSigningCertificate
87+
);
88+
89+
public record AuthUri(
90+
[property: JsonPropertyName("auth_uri")] string AuthUriValue
91+
);
92+
}
93+
}

example/src/WebEid.AspNetCore.Example/Dto/AuthenticateRequestDto.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@
2424

2525
public class AuthenticateRequestDto
2626
{
27-
[JsonPropertyName("auth-token")]
28-
public WebEidAuthToken AuthToken { get; set; }
27+
// Mobile version uses "auth_token"
28+
[JsonPropertyName("auth_token")] public WebEidAuthToken AuthTokenUnderscore { get; set; }
29+
30+
// Desktop version uses "auth-token"
31+
[JsonPropertyName("auth-token")] public WebEidAuthToken AuthTokenDash { get; set; }
32+
33+
// Unified property for backend logic
34+
[JsonIgnore] public WebEidAuthToken AuthToken => AuthTokenDash ?? AuthTokenUnderscore;
2935
}
3036
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2021-2024 Estonian Information System Authority
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
// this software and associated documentation files (the "Software"), to deal in
5+
// the Software without restriction, including without limitation the rights to
6+
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7+
// the Software, and to permit persons to whom the Software is furnished to do so,
8+
// subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all
11+
// copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15+
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
namespace WebEid.AspNetCore.Example.Options
21+
{
22+
using System.ComponentModel.DataAnnotations;
23+
24+
public class WebEidMobileOptions
25+
{
26+
[Required]
27+
[RegularExpression("^.*(?:[^/]|://)$", ErrorMessage = "Base URI must not have a trailing slash")]
28+
public string BaseRequestUri { get; set; } = null!;
29+
30+
public bool RequestSigningCert { get; set; }
31+
}
32+
}

0 commit comments

Comments
 (0)