1
0
mirror of https://github.com/bitwarden/server synced 2025-12-16 00:03:54 +00:00

Implement User-based API Keys (#981)

* added column ApiKey to dbo.User

* added dbo.User.ApiKey to User_Update

* added dbo.User.ApiKey to User_Create

* wrote migration script for implementing dbo.User.ApiKey

* Added ApiKey prop to the User table model

* Created AccountsController method for getting a user's API Key

* Created AccountsController method for rotating a user API key

* Added support to ApiClient for passed-through ClientSecrets when the request comes from the cli

* Added a new conditional to ClientStore to account for user API keys

* Wrote unit tests for new user API Key methods

* Added a refresh of dbo.UserView to new migration script for ApiKey

* Let client_credentials grants into the custom token logic

* Cleanup for ApiKey auth in the CLI feature

* Created user API key on registration

* Removed uneeded code for user API keys

* Changed a .Contains() to a .StartsWith() in ClientStore

* Changed index that an array is searched on

* Added more claims to the user apikey clients

* Moved some claim finding logic to a helper method
This commit is contained in:
Addison Beck
2020-11-10 15:15:29 -05:00
committed by GitHub
parent d9cd7551fe
commit 25a9991908
14 changed files with 540 additions and 59 deletions

View File

@@ -10,6 +10,7 @@ using System.Linq;
using Bit.Core.Identity;
using Microsoft.Extensions.Logging;
using IdentityServer4.Extensions;
using IdentityModel;
namespace Bit.Core.IdentityServer
{
@@ -42,7 +43,8 @@ namespace Bit.Core.IdentityServer
public async Task ValidateAsync(CustomTokenRequestValidationContext context)
{
if (context.Result.ValidatedRequest.GrantType != "authorization_code")
string[] allowedGrantTypes = { "authorization_code", "client_credentials" };
if (!allowedGrantTypes.Contains(context.Result.ValidatedRequest.GrantType))
{
return;
}
@@ -51,7 +53,9 @@ namespace Bit.Core.IdentityServer
protected async override Task<(User, bool)> ValidateContextAsync(CustomTokenRequestValidationContext context)
{
var user = await _userManager.FindByEmailAsync(context.Result.ValidatedRequest.Subject.GetDisplayName());
var email = context.Result.ValidatedRequest.Subject?.GetDisplayName()
?? context.Result.ValidatedRequest.ClientClaims.FirstOrDefault(claim => claim.Type == JwtClaimTypes.Email).Value;
var user = await _userManager.FindByEmailAsync(email);
return (user, user != null);
}