1 | namespace WebApi.Helpers;
|
---|
2 |
|
---|
3 | using Microsoft.Extensions.Options;
|
---|
4 | using Microsoft.IdentityModel.Tokens;
|
---|
5 | using System.IdentityModel.Tokens.Jwt;
|
---|
6 | using backend.Services;
|
---|
7 | using backend.Helpers;
|
---|
8 | using Google.Apis.Auth;
|
---|
9 | using System.Text.Json;
|
---|
10 | using Newtonsoft.Json;
|
---|
11 |
|
---|
12 | public class JwtMiddleware
|
---|
13 | {
|
---|
14 | private readonly RequestDelegate _next;
|
---|
15 | private readonly AppSettings _appSettings;
|
---|
16 | private static readonly HttpClient client = new HttpClient();
|
---|
17 |
|
---|
18 |
|
---|
19 | public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
|
---|
20 | {
|
---|
21 | _next = next;
|
---|
22 | _appSettings = appSettings.Value;
|
---|
23 | }
|
---|
24 |
|
---|
25 | public async Task Invoke(HttpContext context, IUserService userService)
|
---|
26 | {
|
---|
27 | var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
---|
28 |
|
---|
29 | if (token != null && token != "null")
|
---|
30 | await attachUserToContext(context, userService, token);
|
---|
31 |
|
---|
32 | await _next(context);
|
---|
33 | }
|
---|
34 |
|
---|
35 | private async Task attachUserToContext(HttpContext context, IUserService userService, string token)
|
---|
36 | {
|
---|
37 | try
|
---|
38 | {
|
---|
39 | var fbResult = await this.ValidateFacebookToken(token);
|
---|
40 | if (fbResult != null)
|
---|
41 | {
|
---|
42 | context.Items["User"] = fbResult;
|
---|
43 | return;
|
---|
44 | }
|
---|
45 |
|
---|
46 | var tokenHandler = new JwtSecurityTokenHandler();
|
---|
47 | var key = System.Text.Encoding.ASCII.GetBytes(_appSettings.Secret);
|
---|
48 | tokenHandler.ValidateToken(token, new TokenValidationParameters
|
---|
49 | {
|
---|
50 | ValidateIssuerSigningKey = true,
|
---|
51 | IssuerSigningKey = new SymmetricSecurityKey(key),
|
---|
52 | ValidateIssuer = false,
|
---|
53 | ValidateAudience = false,
|
---|
54 | ClockSkew = TimeSpan.Zero
|
---|
55 | }, out SecurityToken validatedToken);
|
---|
56 |
|
---|
57 | var jwtToken = (JwtSecurityToken)validatedToken;
|
---|
58 | var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
|
---|
59 |
|
---|
60 | context.Items["User"] = userId;
|
---|
61 |
|
---|
62 | }
|
---|
63 | catch
|
---|
64 | {
|
---|
65 | try
|
---|
66 | {
|
---|
67 | var result = await GoogleJsonWebSignature.ValidateAsync(token);
|
---|
68 | context.Items["User"] = result.Email;
|
---|
69 | }
|
---|
70 | catch
|
---|
71 | {
|
---|
72 | // do nothing
|
---|
73 | }
|
---|
74 | }
|
---|
75 | }
|
---|
76 |
|
---|
77 | private async Task<string> ValidateFacebookToken(string token)
|
---|
78 | {
|
---|
79 | try
|
---|
80 | {
|
---|
81 | var stringTask = await client.GetStringAsync("https://graph.facebook.com/me?fields=email&access_token=" + token);
|
---|
82 | var obj = JsonConvert.DeserializeObject<FacebookResult>(stringTask);
|
---|
83 | return obj.email;
|
---|
84 | }
|
---|
85 | catch
|
---|
86 | {
|
---|
87 | return null;
|
---|
88 | }
|
---|
89 | }
|
---|
90 |
|
---|
91 | internal class FacebookResult
|
---|
92 | {
|
---|
93 | public string email { get; set; }
|
---|
94 | public string id { get; set; }
|
---|
95 | }
|
---|
96 | } |
---|