File size: 2,400 Bytes
3418204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7f328dd
3418204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64a3c1d
 
3418204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System.Net.Http.Headers;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;

namespace TaskTrackingSystem.WebApp;

/// <summary>
/// Scoped service that creates authorized HttpClient instances for the WebApi.
/// Inject this instead of IHttpClientFactory in Blazor components.
/// </summary>
public class ApiClientService
{
    private readonly IHttpClientFactory _factory;
    private readonly UserSessionState _sessionState;
    private readonly IHttpContextAccessor _httpContextAccessor;

    /// <summary>The base URL of the WebApi (without trailing /api/). Used for direct file download links.</summary>
    public string BaseUrl { get; }

    public ApiClientService(
        IHttpClientFactory factory,
        UserSessionState sessionState,
        IHttpContextAccessor httpContextAccessor,
        IConfiguration configuration)
    {
        _factory = factory;
        _sessionState = sessionState;
        _httpContextAccessor = httpContextAccessor;

        // Strip trailing /api/ so components can build their own paths
        var rawUrl = configuration["WebApi:BaseUrl"] ?? "http://127.0.0.1:5001/api/";
        BaseUrl = rawUrl.TrimEnd('/').EndsWith("/api", StringComparison.OrdinalIgnoreCase)
            ? rawUrl.TrimEnd('/')[..^4]   // remove trailing /api
            : rawUrl.TrimEnd('/');
    }

    public HttpClient CreateClient()
    {
        return CreateClient(null);
    }

    public HttpClient CreateClient(ClaimsPrincipal? user)
    {
        var client = _factory.CreateClient("WebApi");
        var token = ResolveToken(user);

        if (!string.IsNullOrEmpty(token))
        {
            _sessionState.Token = token;
            client.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", token);
        }

        return client;
    }

    public string? GetCurrentToken(ClaimsPrincipal? user = null) => ResolveToken(user);

    private string? ResolveToken(ClaimsPrincipal? user)
    {
        if (!string.IsNullOrEmpty(_sessionState.Token))
        {
            return _sessionState.Token;
        }

        var claimToken = user?.FindFirst("jwt_token")?.Value;
        if (!string.IsNullOrEmpty(claimToken))
        {
            return claimToken;
        }

        return _httpContextAccessor.HttpContext?.User.FindFirst("jwt_token")?.Value;
    }
}