Reputation: 21033
I have a .Net-Core project which uses Identity Server 4 as a token server. Currently, I have set up Identity server 4 to handle some payments through Coinbase. I would like to post back some information back to my api from IdentityServer.
public async Task<IActionResult> AuthorizeTransaction(AuthorizeTransaction transactionInfo)
{
transactionInfo.Transaction.Type = "send";
try
{
var resp = await this._coinbaseOAuthClient
.WithHeader("CB-2FA-TOKEN", transactionInfo.TwoFactorCode)
.Transactions
.SendMoneyAsync(transactionInfo.AccountId, transactionInfo.Transaction);
this.PostBackTransactionData(resp.Data)
}
catch
{
return View("CreateTransaction", transactionInfo);
}
return RedirectToAction("index");
}
protected void PostBackTransactionData(Transaction data)
{
//TODO: Inject api from DI
var confirmTransactionEndpoint = "https://localhost:44377/api/transactions/confirm-payment";
var client = new FlurlClient();
confirmTransactionEndpoint.WithClient(client).PostJsonAsync(data);
}
On my Api I store the data I need in my Database however I'm having trouble on figuring out how I can Authenticate this request.
Normally when you want to verify an application you'd use something like Identity server, overkill to have another token server to verify my token server.
What is a secure way to validate that the request came from my token server (Identity Server 4)?
Upvotes: 0
Views: 996
Reputation: 381
The way I have done this is to use the in-built tools from Identity Server to issue a client JWT and set that as the bearer token to the request back into the API's.
I setup a new Identity Client that contained a specific scope for accessing the API's from Identity and used this client to self issue the above JWT. Then within the API's, I created a new authorization policy for this scope and applied that to certain endpoints within the API.
For example
In Identity Server You can inject IdentityServerTools into your class. This is pre registered for you and is part of the IdentityServer4 namespace
public class SomeService : ISomeService
{
private readonly IdentityServerTools _identityServerTools;
public SomeService(IdentityServerTools identityServerTools)
{
_identityServerTools = identityServerTools;
}
private async Task<string> CreateTokenAsync()
{
// Get client for JWT
var idpClient = _dbContext.Clients.FirstOrDefault(c => c.ClientId == SomeClientId);
// Get scopes to set in JWT
var scopes = idpClient.AllowedScopes.Select(s => s.Scope).ToArray();
// Use in-built Identity Server tools to issue JWT
var token = await _identityServerTools.IssueClientJwtAsync(idpClient.ClientId, idpClient.AccessTokenLifetime, scopes, new[] { "Some Api Name"})
}
}
Then set this token as the bearer token on your request.
In your API Now to authorize this request back in your API's setup an authorization policy on Startup
services.AddAuthorization(options =>
{
options.AddPolicy("PolicyName", policy => {
policy.RequireScope("ScopeName")
})
})
And then on your endpoint in your API's add the following
[Authorize("PolicyName")]
Upvotes: 1