|
8 | 8 | using System; |
9 | 9 | using Microsoft.Extensions.Configuration; |
10 | 10 | using DigitalLearningSolutions.Data.Extensions; |
| 11 | + using DocumentFormat.OpenXml.Bibliography; |
| 12 | + using Microsoft.FeatureManagement.FeatureFilters; |
| 13 | + using System.Net.Http.Headers; |
| 14 | + using System.Net.Http; |
| 15 | + using System.Threading.Tasks; |
11 | 16 |
|
12 | 17 | public interface ITableauConnectionHelperService |
13 | | - { |
14 | | - string GetTableauJwt(string email); |
15 | | - } |
| 18 | + { |
| 19 | + string GetTableauJwt(string email); |
| 20 | + Task<string> AuthenticateUserAsync(string jwtToken); |
| 21 | + } |
16 | 22 | public class TableauConnectionHelper : ITableauConnectionHelperService |
17 | 23 | { |
18 | | - private readonly string connectedAppClient; |
| 24 | + private readonly string connectedAppClientName; |
19 | 25 | private readonly string connectedAppSecretKey; |
20 | 26 | private readonly string connectedAppClientId; |
| 27 | + private readonly string tableauUrl; |
| 28 | + private readonly string dashboardUrl; |
21 | 29 | private readonly string user; |
22 | 30 | public TableauConnectionHelper(IConfiguration config) |
23 | 31 | { |
24 | | - connectedAppClient = config.GetTableauClientName(); |
| 32 | + connectedAppClientName = config.GetTableauClientName(); |
25 | 33 | connectedAppClientId = config.GetTableauClientId(); |
26 | 34 | connectedAppSecretKey = config.GetTableauClientSecret(); |
| 35 | + tableauUrl = config.GetTableauSiteUrl(); |
| 36 | + dashboardUrl = config.GetTableauDashboardUrl(); |
27 | 37 | user = config.GetTableauUser(); |
28 | 38 | } |
29 | 39 | public string GetTableauJwt(string email) |
30 | 40 | { |
31 | 41 | var tokenHandler = new JwtSecurityTokenHandler(); |
32 | | - var key = Encoding.ASCII.GetBytes(connectedAppSecretKey); |
33 | | - |
34 | | - var tokenDescriptor = new SecurityTokenDescriptor |
| 42 | + var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(connectedAppSecretKey)); |
| 43 | + var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); |
| 44 | + var claims = new[] |
35 | 45 | { |
36 | | - Issuer = connectedAppClientId, |
37 | | - Audience = "tableau", |
38 | | - Subject = new ClaimsIdentity(new[] |
39 | | - { |
40 | 46 | new Claim(JwtRegisteredClaimNames.Sub, user), |
41 | | - new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), |
| 47 | + new Claim(JwtRegisteredClaimNames.Iss, connectedAppClientId), |
42 | 48 | new Claim("scp", "tableau:views:embed"), |
43 | | - new Claim("scp", "tableau:metrics:embed"), |
44 | | - new Claim("users.primaryemail", email) |
45 | | - }), |
46 | | - Expires = DateTime.UtcNow.AddMinutes(5), |
47 | | - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature), |
48 | | - Claims = new Dictionary<string, object> |
49 | | - { |
50 | | - { "kid", connectedAppClientId }, |
51 | | - { "iss", connectedAppClient } |
52 | | - } |
| 49 | + new Claim("users.primaryemail", email), |
| 50 | + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), |
| 51 | + new Claim(JwtRegisteredClaimNames.Exp, |
| 52 | + new DateTimeOffset(DateTime.UtcNow.AddMinutes(20)).ToUnixTimeSeconds().ToString()) |
53 | 53 | }; |
54 | 54 |
|
55 | | - var token = tokenHandler.CreateToken(tokenDescriptor); |
56 | | - var tokenString = tokenHandler.WriteToken(token); |
| 55 | + var token = new JwtSecurityToken( |
| 56 | + issuer: connectedAppClientId, |
| 57 | + audience: "tableau", |
| 58 | + claims: claims, |
| 59 | + expires: DateTime.UtcNow.AddMinutes(20), |
| 60 | + signingCredentials: credentials); |
57 | 61 |
|
58 | | - return tokenString; |
| 62 | + return new JwtSecurityTokenHandler().WriteToken(token); |
59 | 63 | } |
60 | 64 |
|
| 65 | + public async Task<string> AuthenticateUserAsync(string jwtToken) |
| 66 | + { |
| 67 | + using (var client = new HttpClient()) |
| 68 | + { |
| 69 | + client.BaseAddress = new Uri(tableauUrl); |
| 70 | + client.DefaultRequestHeaders.Accept.Clear(); |
| 71 | + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); |
| 72 | + |
| 73 | + var requestContent = new StringContent($"{{ \"token\": \"{jwtToken}\" }}", Encoding.UTF8, "application/json"); |
| 74 | + |
| 75 | + HttpResponseMessage response = await client.PostAsync("/api/3.8/auth/signin", requestContent); // Adjust API version as needed |
| 76 | + |
| 77 | + if (response.IsSuccessStatusCode) |
| 78 | + { |
| 79 | + string responseBody = await response.Content.ReadAsStringAsync(); |
| 80 | + // Process the response body if needed |
| 81 | + return dashboardUrl; // Return the response for further processing |
| 82 | + } |
| 83 | + else |
| 84 | + { |
| 85 | + throw new Exception("Failed to authenticate with Tableau Server: " + response.ReasonPhrase); |
| 86 | + } |
| 87 | + } |
| 88 | + } |
61 | 89 | } |
62 | 90 | } |
0 commit comments