JWT Authentication Service











up vote
4
down vote

favorite
1












Recently I've built a service at my work to generate tokens with JWT (JSON Web Token) "protocol", I would like to show you the code and to get comments from you if that's good enough and if there are things to improve.



The service contains 2 folders and 4 classes.




  1. Models Folder


    • IAuthContainerModel (Interface)

    • JWTContainerModel (Implementation)



  2. Managers Folder


    • IAuthService (Interface)

    • JWTService (Implementation)







  • IAuthContainerModel


Code:



using System.Security.Claims;

namespace AuthenticationService.Models
{
public interface IAuthContainerModel
{
#region Members
string SecretKey { get; set; }
string SecurityAlgorithm { get; set; }

Claim Claims { get; set; }
int ExpireMinutes { get; set; }
#endregion
}
}



  • JWTContainerModel


Code:



using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;

namespace AuthenticationService.Models
{
public class JWTContainerModel : IAuthContainerModel
{
#region Public Methods
public int ExpireMinutes { get; set; } = 10080; // 7 days.
public string SecretKey { get; set; } = "TW9zaGVFcmV6UHJpdmF0ZUtleQ=="; // This secret key should be moved to some configurations outter server.
public string SecurityAlgorithm { get; set; } = SecurityAlgorithms.HmacSha256Signature;

public Claim Claims { get; set; }
#endregion
}
}


ExpireMinutes is a default value and SecretKey is also a default value, of course the secret key will be in the configurations section inside the server




  • IAuthService


Code:



using System.Security.Claims;
using System.Collections.Generic;
using AuthenticationService.Models;

namespace AuthenticationService.Managers
{
public interface IAuthService
{
string SecretKey { get; set; }

bool IsTokenValid(string token);
string GenerateToken(IAuthContainerModel model);
IEnumerable<Claim> GetTokenClaims(string token);
}
}



  • JWTService


Code:



using System;
using System.Security.Claims;
using System.Collections.Generic;
using AuthenticationService.Models;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;

namespace AuthenticationService.Managers
{
public class JWTService : IAuthService
{
#region Members
/// <summary>
/// The secret key we use to encrypt out token with.
/// </summary>
public string SecretKey { get; set; }
#endregion

#region Constructor
public JWTService(string secretKey)
{
SecretKey = secretKey;
}
#endregion

#region Public Methods
/// <summary>
/// Validates whether a given token is valid or not, and returns true in case the token is valid otherwise it will return false;
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public bool IsTokenValid(string token)
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Given token is null or empty.");

TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
try
{
ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
return true;
}
catch (Exception)
{
return false;
}
}

/// <summary>
/// Generates token by given model.
/// Validates whether the given model is valid, then gets the symmetric key.
/// Encrypt the token and returns it.
/// </summary>
/// <param name="model"></param>
/// <returns>Generated token.</returns>
public string GenerateToken(IAuthContainerModel model)
{
if (model == null || model.Claims == null || model.Claims.Length == 0)
throw new ArgumentException("Arguments to create token are not valid.");

SecurityTokenDescriptor securityTokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(model.Claims),
Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(model.ExpireMinutes)),
SigningCredentials = new SigningCredentials(GetSymmetricSecurityKey(), model.SecurityAlgorithm)
};

JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
SecurityToken securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
string token = jwtSecurityTokenHandler.WriteToken(securityToken);

return token;
}

/// <summary>
/// Receives the claims of token by given token as string.
/// </summary>
/// <remarks>
/// Pay attention, one the token is FAKE the method will throw an exception.
/// </remarks>
/// <param name="token"></param>
/// <returns>IEnumerable of claims for the given token.</returns>
public IEnumerable<Claim> GetTokenClaims(string token)
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Given token is null or empty.");

TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
try
{
ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
return tokenValid.Claims;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion

#region Private Methods
private SecurityKey GetSymmetricSecurityKey()
{
byte symmetricKey = Convert.FromBase64String(SecretKey);
return new SymmetricSecurityKey(symmetricKey);
}

private TokenValidationParameters GetTokenValidationParameters()
{
return new TokenValidationParameters()
{
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = GetSymmetricSecurityKey()
};
}
#endregion
}
}




What do you say about this code? is it implemented correctly? would you fix it in some way? I will be happy to hear your opinions!










share|improve this question




























    up vote
    4
    down vote

    favorite
    1












    Recently I've built a service at my work to generate tokens with JWT (JSON Web Token) "protocol", I would like to show you the code and to get comments from you if that's good enough and if there are things to improve.



    The service contains 2 folders and 4 classes.




    1. Models Folder


      • IAuthContainerModel (Interface)

      • JWTContainerModel (Implementation)



    2. Managers Folder


      • IAuthService (Interface)

      • JWTService (Implementation)







    • IAuthContainerModel


    Code:



    using System.Security.Claims;

    namespace AuthenticationService.Models
    {
    public interface IAuthContainerModel
    {
    #region Members
    string SecretKey { get; set; }
    string SecurityAlgorithm { get; set; }

    Claim Claims { get; set; }
    int ExpireMinutes { get; set; }
    #endregion
    }
    }



    • JWTContainerModel


    Code:



    using System.Security.Claims;
    using Microsoft.IdentityModel.Tokens;

    namespace AuthenticationService.Models
    {
    public class JWTContainerModel : IAuthContainerModel
    {
    #region Public Methods
    public int ExpireMinutes { get; set; } = 10080; // 7 days.
    public string SecretKey { get; set; } = "TW9zaGVFcmV6UHJpdmF0ZUtleQ=="; // This secret key should be moved to some configurations outter server.
    public string SecurityAlgorithm { get; set; } = SecurityAlgorithms.HmacSha256Signature;

    public Claim Claims { get; set; }
    #endregion
    }
    }


    ExpireMinutes is a default value and SecretKey is also a default value, of course the secret key will be in the configurations section inside the server




    • IAuthService


    Code:



    using System.Security.Claims;
    using System.Collections.Generic;
    using AuthenticationService.Models;

    namespace AuthenticationService.Managers
    {
    public interface IAuthService
    {
    string SecretKey { get; set; }

    bool IsTokenValid(string token);
    string GenerateToken(IAuthContainerModel model);
    IEnumerable<Claim> GetTokenClaims(string token);
    }
    }



    • JWTService


    Code:



    using System;
    using System.Security.Claims;
    using System.Collections.Generic;
    using AuthenticationService.Models;
    using Microsoft.IdentityModel.Tokens;
    using System.IdentityModel.Tokens.Jwt;

    namespace AuthenticationService.Managers
    {
    public class JWTService : IAuthService
    {
    #region Members
    /// <summary>
    /// The secret key we use to encrypt out token with.
    /// </summary>
    public string SecretKey { get; set; }
    #endregion

    #region Constructor
    public JWTService(string secretKey)
    {
    SecretKey = secretKey;
    }
    #endregion

    #region Public Methods
    /// <summary>
    /// Validates whether a given token is valid or not, and returns true in case the token is valid otherwise it will return false;
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public bool IsTokenValid(string token)
    {
    if (string.IsNullOrEmpty(token))
    throw new ArgumentException("Given token is null or empty.");

    TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

    JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    try
    {
    ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
    return true;
    }
    catch (Exception)
    {
    return false;
    }
    }

    /// <summary>
    /// Generates token by given model.
    /// Validates whether the given model is valid, then gets the symmetric key.
    /// Encrypt the token and returns it.
    /// </summary>
    /// <param name="model"></param>
    /// <returns>Generated token.</returns>
    public string GenerateToken(IAuthContainerModel model)
    {
    if (model == null || model.Claims == null || model.Claims.Length == 0)
    throw new ArgumentException("Arguments to create token are not valid.");

    SecurityTokenDescriptor securityTokenDescriptor = new SecurityTokenDescriptor
    {
    Subject = new ClaimsIdentity(model.Claims),
    Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(model.ExpireMinutes)),
    SigningCredentials = new SigningCredentials(GetSymmetricSecurityKey(), model.SecurityAlgorithm)
    };

    JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    SecurityToken securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
    string token = jwtSecurityTokenHandler.WriteToken(securityToken);

    return token;
    }

    /// <summary>
    /// Receives the claims of token by given token as string.
    /// </summary>
    /// <remarks>
    /// Pay attention, one the token is FAKE the method will throw an exception.
    /// </remarks>
    /// <param name="token"></param>
    /// <returns>IEnumerable of claims for the given token.</returns>
    public IEnumerable<Claim> GetTokenClaims(string token)
    {
    if (string.IsNullOrEmpty(token))
    throw new ArgumentException("Given token is null or empty.");

    TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

    JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    try
    {
    ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
    return tokenValid.Claims;
    }
    catch (Exception ex)
    {
    throw ex;
    }
    }
    #endregion

    #region Private Methods
    private SecurityKey GetSymmetricSecurityKey()
    {
    byte symmetricKey = Convert.FromBase64String(SecretKey);
    return new SymmetricSecurityKey(symmetricKey);
    }

    private TokenValidationParameters GetTokenValidationParameters()
    {
    return new TokenValidationParameters()
    {
    ValidateIssuer = false,
    ValidateAudience = false,
    IssuerSigningKey = GetSymmetricSecurityKey()
    };
    }
    #endregion
    }
    }




    What do you say about this code? is it implemented correctly? would you fix it in some way? I will be happy to hear your opinions!










    share|improve this question


























      up vote
      4
      down vote

      favorite
      1









      up vote
      4
      down vote

      favorite
      1






      1





      Recently I've built a service at my work to generate tokens with JWT (JSON Web Token) "protocol", I would like to show you the code and to get comments from you if that's good enough and if there are things to improve.



      The service contains 2 folders and 4 classes.




      1. Models Folder


        • IAuthContainerModel (Interface)

        • JWTContainerModel (Implementation)



      2. Managers Folder


        • IAuthService (Interface)

        • JWTService (Implementation)







      • IAuthContainerModel


      Code:



      using System.Security.Claims;

      namespace AuthenticationService.Models
      {
      public interface IAuthContainerModel
      {
      #region Members
      string SecretKey { get; set; }
      string SecurityAlgorithm { get; set; }

      Claim Claims { get; set; }
      int ExpireMinutes { get; set; }
      #endregion
      }
      }



      • JWTContainerModel


      Code:



      using System.Security.Claims;
      using Microsoft.IdentityModel.Tokens;

      namespace AuthenticationService.Models
      {
      public class JWTContainerModel : IAuthContainerModel
      {
      #region Public Methods
      public int ExpireMinutes { get; set; } = 10080; // 7 days.
      public string SecretKey { get; set; } = "TW9zaGVFcmV6UHJpdmF0ZUtleQ=="; // This secret key should be moved to some configurations outter server.
      public string SecurityAlgorithm { get; set; } = SecurityAlgorithms.HmacSha256Signature;

      public Claim Claims { get; set; }
      #endregion
      }
      }


      ExpireMinutes is a default value and SecretKey is also a default value, of course the secret key will be in the configurations section inside the server




      • IAuthService


      Code:



      using System.Security.Claims;
      using System.Collections.Generic;
      using AuthenticationService.Models;

      namespace AuthenticationService.Managers
      {
      public interface IAuthService
      {
      string SecretKey { get; set; }

      bool IsTokenValid(string token);
      string GenerateToken(IAuthContainerModel model);
      IEnumerable<Claim> GetTokenClaims(string token);
      }
      }



      • JWTService


      Code:



      using System;
      using System.Security.Claims;
      using System.Collections.Generic;
      using AuthenticationService.Models;
      using Microsoft.IdentityModel.Tokens;
      using System.IdentityModel.Tokens.Jwt;

      namespace AuthenticationService.Managers
      {
      public class JWTService : IAuthService
      {
      #region Members
      /// <summary>
      /// The secret key we use to encrypt out token with.
      /// </summary>
      public string SecretKey { get; set; }
      #endregion

      #region Constructor
      public JWTService(string secretKey)
      {
      SecretKey = secretKey;
      }
      #endregion

      #region Public Methods
      /// <summary>
      /// Validates whether a given token is valid or not, and returns true in case the token is valid otherwise it will return false;
      /// </summary>
      /// <param name="token"></param>
      /// <returns></returns>
      public bool IsTokenValid(string token)
      {
      if (string.IsNullOrEmpty(token))
      throw new ArgumentException("Given token is null or empty.");

      TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

      JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
      try
      {
      ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
      return true;
      }
      catch (Exception)
      {
      return false;
      }
      }

      /// <summary>
      /// Generates token by given model.
      /// Validates whether the given model is valid, then gets the symmetric key.
      /// Encrypt the token and returns it.
      /// </summary>
      /// <param name="model"></param>
      /// <returns>Generated token.</returns>
      public string GenerateToken(IAuthContainerModel model)
      {
      if (model == null || model.Claims == null || model.Claims.Length == 0)
      throw new ArgumentException("Arguments to create token are not valid.");

      SecurityTokenDescriptor securityTokenDescriptor = new SecurityTokenDescriptor
      {
      Subject = new ClaimsIdentity(model.Claims),
      Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(model.ExpireMinutes)),
      SigningCredentials = new SigningCredentials(GetSymmetricSecurityKey(), model.SecurityAlgorithm)
      };

      JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
      SecurityToken securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
      string token = jwtSecurityTokenHandler.WriteToken(securityToken);

      return token;
      }

      /// <summary>
      /// Receives the claims of token by given token as string.
      /// </summary>
      /// <remarks>
      /// Pay attention, one the token is FAKE the method will throw an exception.
      /// </remarks>
      /// <param name="token"></param>
      /// <returns>IEnumerable of claims for the given token.</returns>
      public IEnumerable<Claim> GetTokenClaims(string token)
      {
      if (string.IsNullOrEmpty(token))
      throw new ArgumentException("Given token is null or empty.");

      TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

      JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
      try
      {
      ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
      return tokenValid.Claims;
      }
      catch (Exception ex)
      {
      throw ex;
      }
      }
      #endregion

      #region Private Methods
      private SecurityKey GetSymmetricSecurityKey()
      {
      byte symmetricKey = Convert.FromBase64String(SecretKey);
      return new SymmetricSecurityKey(symmetricKey);
      }

      private TokenValidationParameters GetTokenValidationParameters()
      {
      return new TokenValidationParameters()
      {
      ValidateIssuer = false,
      ValidateAudience = false,
      IssuerSigningKey = GetSymmetricSecurityKey()
      };
      }
      #endregion
      }
      }




      What do you say about this code? is it implemented correctly? would you fix it in some way? I will be happy to hear your opinions!










      share|improve this question















      Recently I've built a service at my work to generate tokens with JWT (JSON Web Token) "protocol", I would like to show you the code and to get comments from you if that's good enough and if there are things to improve.



      The service contains 2 folders and 4 classes.




      1. Models Folder


        • IAuthContainerModel (Interface)

        • JWTContainerModel (Implementation)



      2. Managers Folder


        • IAuthService (Interface)

        • JWTService (Implementation)







      • IAuthContainerModel


      Code:



      using System.Security.Claims;

      namespace AuthenticationService.Models
      {
      public interface IAuthContainerModel
      {
      #region Members
      string SecretKey { get; set; }
      string SecurityAlgorithm { get; set; }

      Claim Claims { get; set; }
      int ExpireMinutes { get; set; }
      #endregion
      }
      }



      • JWTContainerModel


      Code:



      using System.Security.Claims;
      using Microsoft.IdentityModel.Tokens;

      namespace AuthenticationService.Models
      {
      public class JWTContainerModel : IAuthContainerModel
      {
      #region Public Methods
      public int ExpireMinutes { get; set; } = 10080; // 7 days.
      public string SecretKey { get; set; } = "TW9zaGVFcmV6UHJpdmF0ZUtleQ=="; // This secret key should be moved to some configurations outter server.
      public string SecurityAlgorithm { get; set; } = SecurityAlgorithms.HmacSha256Signature;

      public Claim Claims { get; set; }
      #endregion
      }
      }


      ExpireMinutes is a default value and SecretKey is also a default value, of course the secret key will be in the configurations section inside the server




      • IAuthService


      Code:



      using System.Security.Claims;
      using System.Collections.Generic;
      using AuthenticationService.Models;

      namespace AuthenticationService.Managers
      {
      public interface IAuthService
      {
      string SecretKey { get; set; }

      bool IsTokenValid(string token);
      string GenerateToken(IAuthContainerModel model);
      IEnumerable<Claim> GetTokenClaims(string token);
      }
      }



      • JWTService


      Code:



      using System;
      using System.Security.Claims;
      using System.Collections.Generic;
      using AuthenticationService.Models;
      using Microsoft.IdentityModel.Tokens;
      using System.IdentityModel.Tokens.Jwt;

      namespace AuthenticationService.Managers
      {
      public class JWTService : IAuthService
      {
      #region Members
      /// <summary>
      /// The secret key we use to encrypt out token with.
      /// </summary>
      public string SecretKey { get; set; }
      #endregion

      #region Constructor
      public JWTService(string secretKey)
      {
      SecretKey = secretKey;
      }
      #endregion

      #region Public Methods
      /// <summary>
      /// Validates whether a given token is valid or not, and returns true in case the token is valid otherwise it will return false;
      /// </summary>
      /// <param name="token"></param>
      /// <returns></returns>
      public bool IsTokenValid(string token)
      {
      if (string.IsNullOrEmpty(token))
      throw new ArgumentException("Given token is null or empty.");

      TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

      JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
      try
      {
      ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
      return true;
      }
      catch (Exception)
      {
      return false;
      }
      }

      /// <summary>
      /// Generates token by given model.
      /// Validates whether the given model is valid, then gets the symmetric key.
      /// Encrypt the token and returns it.
      /// </summary>
      /// <param name="model"></param>
      /// <returns>Generated token.</returns>
      public string GenerateToken(IAuthContainerModel model)
      {
      if (model == null || model.Claims == null || model.Claims.Length == 0)
      throw new ArgumentException("Arguments to create token are not valid.");

      SecurityTokenDescriptor securityTokenDescriptor = new SecurityTokenDescriptor
      {
      Subject = new ClaimsIdentity(model.Claims),
      Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(model.ExpireMinutes)),
      SigningCredentials = new SigningCredentials(GetSymmetricSecurityKey(), model.SecurityAlgorithm)
      };

      JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
      SecurityToken securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
      string token = jwtSecurityTokenHandler.WriteToken(securityToken);

      return token;
      }

      /// <summary>
      /// Receives the claims of token by given token as string.
      /// </summary>
      /// <remarks>
      /// Pay attention, one the token is FAKE the method will throw an exception.
      /// </remarks>
      /// <param name="token"></param>
      /// <returns>IEnumerable of claims for the given token.</returns>
      public IEnumerable<Claim> GetTokenClaims(string token)
      {
      if (string.IsNullOrEmpty(token))
      throw new ArgumentException("Given token is null or empty.");

      TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters();

      JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
      try
      {
      ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
      return tokenValid.Claims;
      }
      catch (Exception ex)
      {
      throw ex;
      }
      }
      #endregion

      #region Private Methods
      private SecurityKey GetSymmetricSecurityKey()
      {
      byte symmetricKey = Convert.FromBase64String(SecretKey);
      return new SymmetricSecurityKey(symmetricKey);
      }

      private TokenValidationParameters GetTokenValidationParameters()
      {
      return new TokenValidationParameters()
      {
      ValidateIssuer = false,
      ValidateAudience = false,
      IssuerSigningKey = GetSymmetricSecurityKey()
      };
      }
      #endregion
      }
      }




      What do you say about this code? is it implemented correctly? would you fix it in some way? I will be happy to hear your opinions!







      c# object-oriented authentication jwt






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 16 at 6:55









      t3chb0t

      33.8k746111




      33.8k746111










      asked Sep 16 at 6:53









      Moshe Binieli

      211




      211






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          It looks fine to me, I just a few minor suggestions.



          catch (Exception ex)
          {
          throw ex;
          }


          You probably left this in by accident, but you're better off without a catch block if all you're going to do is re-throw. And if you are going to keep this block, throw; is always preferable to throw ex;



          I question the wisdom of having a "default" key specified in the code. It seems to me that it should always read from outside and complain loudly if it fails. With a usable default key, it opens the possibility that it could use the wrong key without you knowing about it.






          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f203807%2fjwt-authentication-service%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote













            It looks fine to me, I just a few minor suggestions.



            catch (Exception ex)
            {
            throw ex;
            }


            You probably left this in by accident, but you're better off without a catch block if all you're going to do is re-throw. And if you are going to keep this block, throw; is always preferable to throw ex;



            I question the wisdom of having a "default" key specified in the code. It seems to me that it should always read from outside and complain loudly if it fails. With a usable default key, it opens the possibility that it could use the wrong key without you knowing about it.






            share|improve this answer

























              up vote
              0
              down vote













              It looks fine to me, I just a few minor suggestions.



              catch (Exception ex)
              {
              throw ex;
              }


              You probably left this in by accident, but you're better off without a catch block if all you're going to do is re-throw. And if you are going to keep this block, throw; is always preferable to throw ex;



              I question the wisdom of having a "default" key specified in the code. It seems to me that it should always read from outside and complain loudly if it fails. With a usable default key, it opens the possibility that it could use the wrong key without you knowing about it.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                It looks fine to me, I just a few minor suggestions.



                catch (Exception ex)
                {
                throw ex;
                }


                You probably left this in by accident, but you're better off without a catch block if all you're going to do is re-throw. And if you are going to keep this block, throw; is always preferable to throw ex;



                I question the wisdom of having a "default" key specified in the code. It seems to me that it should always read from outside and complain loudly if it fails. With a usable default key, it opens the possibility that it could use the wrong key without you knowing about it.






                share|improve this answer












                It looks fine to me, I just a few minor suggestions.



                catch (Exception ex)
                {
                throw ex;
                }


                You probably left this in by accident, but you're better off without a catch block if all you're going to do is re-throw. And if you are going to keep this block, throw; is always preferable to throw ex;



                I question the wisdom of having a "default" key specified in the code. It seems to me that it should always read from outside and complain loudly if it fails. With a usable default key, it opens the possibility that it could use the wrong key without you knowing about it.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 1 hour ago









                Pierre Menard

                1,577721




                1,577721






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f203807%2fjwt-authentication-service%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Quarter-circle Tiles

                    build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

                    Mont Emei