-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGoogleMyCustomIdentityTokenExchangeHandler.cs
104 lines (94 loc) · 4.15 KB
/
GoogleMyCustomIdentityTokenExchangeHandler.cs
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GraphQLPlay.Contracts;
using Microsoft.AspNetCore.Http;
using TokenExchange.Contracts.Extensions;
using Utils.Models;
namespace TokenExchange.Contracts.Services
{
public class GoogleMyCustomIdentityTokenExchangeHandler : ITokenExchangeHandler
{
private IHttpContextAccessor _httpContextAssessor;
private ISummaryLogger _summaryLogger;
private ITokenValidator _tokenValidator;
private ITokenMintingService _tokenMintingService;
public GoogleMyCustomIdentityTokenExchangeHandler(
ITokenValidator tokenValidator,
ITokenMintingService tokenMintingService,
IHttpContextAccessor httpContextAssessor,
ISummaryLogger summaryLogger)
{
_tokenValidator = tokenValidator;
_tokenMintingService = tokenMintingService;
_httpContextAssessor = httpContextAssessor;
_summaryLogger = summaryLogger;
}
public string Name => "google-my-custom";
public async Task<List<TokenExchangeResponse>> ProcessExchangeAsync(TokenExchangeRequest tokenExchangeRequest)
{
if (tokenExchangeRequest.Extras == null || tokenExchangeRequest.Extras.Count == 0)
{
throw new Exception($"{Name}: We require that extras be populated!");
}
List<ValidatedToken> validatedIdentityTokens = new List<ValidatedToken>();
foreach (var item in tokenExchangeRequest.Tokens)
{
var principal = await _tokenValidator.ValidateTokenAsync(new TokenDescriptor
{
TokenScheme = item.TokenScheme,
Token = item.Token
});
var sub = principal.GetSubjectFromPincipal();
if (string.IsNullOrEmpty(sub))
{
_summaryLogger.Add("subject", "A subject was not found in the ClaimsPrincipal object!");
throw new Exception("A subject was not found in the ClaimsPrincipal object!");
}
validatedIdentityTokens.Add(new ValidatedToken
{
Token = item.Token,
TokenScheme = item.TokenScheme,
Principal = principal
});
}
// for this demo, lets assume all the extras are roles.
var roles = tokenExchangeRequest.Extras;
roles.Add("user");
ResourceOwnerTokenRequest resourceOwnerTokenRequest = new ResourceOwnerTokenRequest()
{
AccessTokenLifetime = 3600,
ArbitraryClaims = new Dictionary<string, List<string>>()
{
{ "role", roles }
},
Scope = "offline_access graphQLPlay",
Subject = validatedIdentityTokens[0].Principal.GetSubjectFromPincipal(),
ClientId = "arbitrary-resource-owner-client"
};
var response = await _tokenMintingService.MintResourceOwnerTokenAsync(resourceOwnerTokenRequest);
if (response.IsError)
{
throw new Exception(response.Error);
}
var tokenExchangeResponse = new TokenExchangeResponse()
{
accessToken = new AccessTokenResponse()
{
hint = nameof(GoogleMyCustomIdentityTokenExchangeHandler),
access_token = response.AccessToken,
refresh_token = response.RefreshToken,
expires_in = response.ExpiresIn,
token_type = response.TokenType,
authority =
$"{_httpContextAssessor.HttpContext.Request.Scheme}://{_httpContextAssessor.HttpContext.Request.Host}",
HttpHeaders = new List<HttpHeader>
{
new HttpHeader() {Name = "x-authScheme", Value = response.Scheme}
}
}
};
return new List<TokenExchangeResponse>() { tokenExchangeResponse };
}
}
}