This repository has been archived by the owner on Sep 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
/
SimpleAuthorizationServerProvider.cs
147 lines (120 loc) · 5.07 KB
/
SimpleAuthorizationServerProvider.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using YellowNotes.Api.Services;
using YellowNotes.Api.Utils;
namespace YellowNotes.Api.Providers
{
internal class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
private readonly IAuthService _authService;
private readonly IClientService _clientService;
public SimpleAuthorizationServerProvider(IAuthService authService, IClientService clientService)
{
_authService = authService;
_clientService = clientService;
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
//looking in Authorization header using Basic scheme
if (!context.TryGetBasicCredentials(out var clientId, out var clientSecret))
{
//looking as x-www-form-urlencoded
context.TryGetFormCredentials(out clientId, out clientSecret);
}
if (!AuthenticateClient(context, clientId, clientSecret))
{
return Task.CompletedTask;
}
var deviceId = context.Parameters.Get("device");
context.OwinContext.Set("device", deviceId);
context.Validated();
return Task.CompletedTask;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
await Task.CompletedTask;
string device = context.OwinContext.Get<string>("device");
if (!ValidateDevice(device))
{
context.SetError("invalid_device", "device must be sent");
return;
}
if (!_authService.AuthenticateUser(context.UserName, HashProvider.Get(context.Password), out var user))
{
context.SetError("invalid_grant", "user name or password is invalid");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ApiConstants.ClaimDevice, device));
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{"fullname", user.FullName},
{"as:client_id", context.ClientId},
});
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
}
public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
var originalClient = context.Ticket.Properties.Dictionary["as:client_id"];
var currentClient = context.ClientId;
if (originalClient != currentClient)
{
context.SetError("invalid_client_id", "refresh_token issued by different client_id");
return Task.CompletedTask;
}
var identity = new ClaimsIdentity(context.Ticket.Identity);
identity.AddClaim(new Claim("newClaim", "someValue"));
context.Ticket.Properties.Dictionary.Add("newProp", "newValue");
var ticket = new AuthenticationTicket(identity, context.Ticket.Properties);
context.Validated(ticket);
return Task.CompletedTask;
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (var property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.CompletedTask;
}
private bool AuthenticateClient(OAuthValidateClientAuthenticationContext context, string clientId, string clientSecret)
{
if (string.IsNullOrWhiteSpace(clientId))
{
context.SetError("invalid_client_id", "client_id must be supplied");
return false;
}
if (string.IsNullOrWhiteSpace(clientSecret))
{
context.SetError("invalid_client_secret", "client_secret must be supplied");
return false;
}
var client = _clientService.GetClient(clientId);
if (client == null)
{
context.SetError("invalid_client_id", "client_id is invalid");
return false;
}
if (client.Secret != HashProvider.Get(clientSecret))
{
context.SetError("invalid_client_secret", "client_secret is invalid");
return false;
}
if (!client.Active)
{
context.SetError("invalid_client", "client is inactive");
return false;
}
return true;
}
private static bool ValidateDevice(string device)
{
return !string.IsNullOrWhiteSpace(device);
}
}
}