Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to do with JWT client_id on Javascript backend with ASP.NET Web API

I'm trying to implement JWT authorization in a project. However in order to successfully get the token I have to pass client_id from AngularJS frontend to ASP.NET Web API backend and as far as I know it is not secure at all. So could someone please give me a hint about what should I be doing in my situation.

On JS side -

var data = 'grant_type=password&username='
                    + loginData.Email + '&password=' + loginData.Password + '&client_id=' + client_id;
$http.post('/oauth2/token', data); //Code omitted

I'm using this guide for creating a Jwt authorization, for the most part. Except I have an app on one domain, so here is what my Startup.cs looks like -

public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();               
            config.MapHttpAttributeRoutes();    
            ConfigureOAuth(app);    
            ConfigureValidationOAuth(app);
        }

private static void ConfigureOAuth(IAppBuilder app)
        {
            var oAuthServerOptions = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/oauth2/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
                Provider = new CustomOAuthProvider(),
                AccessTokenFormat = new CustomJwtFormat(ConfigurationManager.AppSettings["owin:issuer"])
            };

            app.UseOAuthAuthorizationServer(oAuthServerOptions);
        }   

 private static void ConfigureValidationOAuth(IAppBuilder app)
    {
        var issuer = ConfigurationManager.AppSettings["owin:issuer"];
        var audience = ConfigurationManager.AppSettings["owin:audience"];
        var secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["owin:secret"]);

        //Api controllers with [Authorize] attribute will be validated with Jwt
        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] {audience},
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
                }
            });
    }
like image 385
renchan Avatar asked Oct 31 '22 14:10

renchan


1 Answers

JWT authentication and authorization should work like so:

  1. pass username and pass to server
  2. server checks the user data and generates the JWT token which should be in this format: (check out JWT.io for more info)

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

  3. the JWT token should be stored client side in a local storage

  4. to make your life easier you should create an angular HTTP request interceptor that automatically appends the saved JWT token to the request headers. Something like this:

myApp.factory('jwt-interceptor', ['$q', '$window', function($q, $window) { return { request: function(request) { request.headers['Authorization'] = 'Bearer ' + $window.localStorage.token; return request; }, responseError: function(response) {
return $q.reject(response); } }; }]).config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('jwt-interceptor'); }]);

  1. server should read the header param named Authorization, decompile the token and check if the payload:

    a. was decompiled correctly and the payload is intact

    b. check if the expiry timestamp in the payload is bigger then the current timestamp

    c. other user permission related checks (if required)

like image 55
Synapse Avatar answered Nov 15 '22 04:11

Synapse