How do I generate a token internally in OpenIddict in order to call other API's during login?

222 Views Asked by At

I have an OpenIddict server that needs to call other services during login. One of the services is a user service where I store all the users that can login. However, the user service needs to be protected and thus require a valid token but I can't seem to find a way to generate a token manually.

I have found the IOpenIddictTokenManager and been able to create a new token but it does not contain the actual access token. In the code below the payload is null and so is the value in the database, as it should. The client I am using is configured for ClientCredentials but I have tried other clients as well with the same result.

        var app = await _applicationManager.FindByClientIdAsync("<clientId>");
        var token = await _tokenManager.CreateAsync(new OpenIddictTokenDescriptor()
        {
            ApplicationId = await _applicationManager.GetIdAsync(app),
            CreationDate = DateTime.UtcNow,
            ExpirationDate = DateTime.UtcNow.AddMinutes(1),
            Type = "access_token",
            Subject = "<subject>"
        });
        
        var payload = await _tokenManager.GetPayloadAsync(token);
1

There are 1 best solutions below

1
On

I cloned the OpenIddict repository and did some investigations and came up with the following solution.

public class TokenGenerator : ITokenGenerator
{
    private readonly IOptions<OpenIddictServerOptions> _options;

    public TokenGenerator(IOptions<OpenIddictServerOptions> options)
    {
        _options = options;
    }
    public string GenerateToken(params string[] scopes)
    {
        var claims = scopes.Select(a => new Claim(OpenIddictConstants.Claims.Scope, a)).ToList();
        var claimsIdentity = new ClaimsIdentity(claims);
        var descriptor = new SecurityTokenDescriptor
        {
            Claims = claims.ToDictionary(a => a.Type, a => (object)a.Value),
            Expires = DateTime.UtcNow.AddMinutes(1),
            IssuedAt = DateTime.UtcNow,
            Issuer = _options.Value.Issuer?.ToString().Trim('/') ?? "",
            SigningCredentials = _options.Value.SigningCredentials.First(),
            Subject = claimsIdentity,
            TokenType = OpenIddictConstants.JsonWebTokenTypes.AccessToken,
        };
        var token = new JsonWebTokenHandler().CreateToken(descriptor);
        return token;
    }   
}

public interface ITokenGenerator
{
    string GenerateToken(params string[] scopes);
}

I can now use this inside of a DelegateHandler on the HttpClients and issue a token on demand when communicating with other services that require authorization.