This project has moved and is read-only. For the latest updates, please go here.

Recommended way to issue access tokens in JWT format from OAuthAuthorizationServer

Mar 15, 2014 at 1:06 PM
I want issue access tokens in JWT format from my OAuth 2.0 authorization server built on top of OAuthAuthorizationServerMiddleware.

This will probably be happen by setting the proper type to the OAuthAuthorizationServerOptions.AccessTokenFormat and I can see that we have an ISecureDataFormat<AuthenticationTicket> implementation for JWT (JwtFormat) distributed through Microsoft.Owin.Security.Jwt nuget package. However, it's Protect method is as below:
public string Protect(AuthenticationTicket data)
{
    throw new NotSupportedException();
}
What is the recommended way to issue access tokens in JWT format? I don't think I can use JwtFormat for that.
Mar 15, 2014 at 8:30 PM
Created the below Format to produce JWT:
    public class JwtWriterFormat : ISecureDataFormat<AuthenticationTicket>
    {
        private readonly ISigningCredentialsProvider _signingCredentialsProvider;
        private readonly TimeSpan _defaultJwtExpireTimeSpan;

        public JwtWriterFormat(ISigningCredentialsProvider signingCredentialsProvider, TimeSpan defaultJwtExpireTimeSpan)
        {
            _signingCredentialsProvider = signingCredentialsProvider;
            _defaultJwtExpireTimeSpan = defaultJwtExpireTimeSpan;
        }

        public string Protect(AuthenticationTicket data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            string issuer;
            string audience;
            data.Properties.Dictionary.TryGetValue(JwtWriterFormatConstants.IssuerKey, out issuer);
            data.Properties.Dictionary.TryGetValue(JwtWriterFormatConstants.AudienceKey, out audience);

            if (issuer == null) throw new InvalidOperationException("AuthenticationTicket.Properties does not include 'Issuer' value.");
            if (audience == null) throw new InvalidOperationException("AuthenticationTicket.Properties does not include 'Audience' value.");

            DateTime issuedUtc = data.Properties.IssuedUtc.HasValue
                ? GetUtcDateTime(data.Properties.IssuedUtc.Value)
                : DateTime.UtcNow;

            DateTime expiresUtc = data.Properties.ExpiresUtc.HasValue
                ? GetUtcDateTime(data.Properties.ExpiresUtc.Value)
                : DateTime.UtcNow.Add(_defaultJwtExpireTimeSpan);

            SigningCredentials signingCredentials = _signingCredentialsProvider.GetSigningCredentials(issuer, audience);
            JwtSecurityToken token = new JwtSecurityToken(
                issuer: issuer,
                audience: audience,
                claims: data.Identity.Claims,
                lifetime: new Lifetime(issuedUtc, expiresUtc),
                signingCredentials: signingCredentials
                );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        public AuthenticationTicket Unprotect(string protectedText)
        {
            throw new NotImplementedException();
        }

        // privates

        private DateTime GetUtcDateTime(DateTimeOffset dateTime)
        {
            return  new DateTime(
                    dateTime.Year,
                    dateTime.Month,
                    dateTime.Day,
                    dateTime.Hour,
                    dateTime.Minute,
                    dateTime.Second,
                    DateTimeKind.Utc
                );
        }
    }
using this as the AccessTokenFormat. Works great AFA I can see but feedback welcome. I also wonder why you guys didn't implement the Protect method on JwtFormat.
Marked as answer by Tratcher on 11/19/2014 at 9:25 AM
Mar 15, 2014 at 9:39 PM
I've already created a ticket. Feel free to upvote it: https://katanaproject.codeplex.com/workitem/209
Mar 16, 2014 at 12:09 PM
upvoted it! thanks!
Apr 30, 2014 at 7:12 PM
Have you considered using JwtSecurityTokenHandler.CreateToken?
Also if you are creating a lot of tokens, then you will want to investigate hooking your own SignatureProvider so that each signature doesn't require creating a new crypto service provider.
Jul 8, 2014 at 2:14 AM
Edited Jul 8, 2014 at 2:15 AM
Am i correct in assuming that the default OAuthAuthorizationServerMiddleware uses it's own custom method of generating the token (and when hosted within IIS using the machine key to sign this). Does this mean that the only way for receiving clients of this token to retrieve their claims is by also including them in OAuthTokenEndpointContext.AdditionalResponseParameters (since they don't know how to read the contents of the token).

Is this a standard / ideal implementation approach from an OAuth provider, or is the use of JWT seen as better?