1

I am working on a sample SPA application to get my hands on ASP.NET 5. I am using Visual Studio Community 2015 RC.

I am stuck on Bearer token generation. I need to generate a token for AngularJS app so that I can call and authenticate APIs.

  • Just curious, why you need Bearer token, OWIN + Basic authentication is not enough for your case? – cuongle May 20 '15 at 15:31
  • What would be the best approach to consume MVC 6 Web APIs to AngularJs considering I have to authorize Controllers based on Role? – Rajinder Singh May 21 '15 at 02:02
  • If your web api is call from angularjs which is on the same host, you can use OWIN cookie authentication middleware. – cuongle May 21 '15 at 08:02
  • Thanks for reply. No API will be hosted on different host. There must be something to use in that case.. – Rajinder Singh May 21 '15 at 10:19
  • So your case, use OWIN would be simplest, it works like Forms Authentication before which is using cookie. But if in the future, you have to support native client or mobile app, use basic authentication beside owin cookie authentication. Oauth2 would be more complicated, my opinion, I just only need OAuth2 for Single Sign On. – cuongle May 21 '15 at 10:52
  • But if you still want use OAuth2, follow these article: http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ – cuongle May 21 '15 at 10:56

2 Answers2

0

Have a look at this similar question Token Based Authentication in ASP.NET Core

Matt DeKrey's answer may solve your problem.

Community
  • 1
  • 1
CemilF
  • 126
  • 1
  • 6
0

You can implement claim based authentication like below;

Add a method in Startup.cs

     public void ConfigureAuthentication(IServiceCollection services)
        {
            var key = Encoding.ASCII.GetBytes("very-secret-much-complex-secret");
            var tokenValidationParameters = new TokenValidationParameters
            {
                // The signing key must match

                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                // Validate the JWT issuer (Iss) claim
                ValidateIssuer = false,
                //ValidIssuers = validIssuerList,

                // Validate the JWT audience (Aud) claim
                ValidateAudience = false,
                //ValidAudiences = validAudienceList,

                // Validate token expiration
                ValidateLifetime = true,

                ClockSkew = TimeSpan.Zero
            };

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            })
            .AddJwtBearer(o =>
            {
                o.TokenValidationParameters = tokenValidationParameters;
            });
        }

And call this method in ConfigureServices method on Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            //DI Injections
            services.AddScoped<IAuthService, AuthService>();
            services.AddScoped<IAudienceService, AudienceService>();


            ConfigureAuthentication(services);
            services.AddMvc(
               options =>
               {
                   var policy = new AuthorizationPolicyBuilder()
                                       .RequireAuthenticatedUser()
                                       .Build();
                   options.Filters.Add(new AuthorizeFilter(policy));
               });
        }

Then, UseAuthentication in the Configure method

   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }


            app.UseAuthentication();

            app.UseHttpsRedirection();
            app.UseMvc();
        }

Above we configured our API to use JWT authentication as authorization layer. Lets see how we generate a valid token below;

  public async Task<string> Authenticate(string apiKey, string sharedSecret)
        {
            //get audience by apikey and password from database
            //create token from createdobject 
            var audience = await audienceService.GetByCredentials(apiKey, sharedSecret);
            // return null if auudience not found
            if (audience == null)
                return null;

            // authentication successful so generate jwt token
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes("very-secret-much-complex-secret");
            var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature);

            //arange claims from permissions
            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, audience.Name),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            };
            claims.AddRange(audience.Permissions.Where(p => p.Value).Select(p => new Claim(ClaimsIdentity.DefaultRoleClaimType, p.Key.GetHashCode().ToString())));

            var token = new JwtSecurityToken(
                audience.Name,
                audience.Name,
                claims,
                expires: DateTime.UtcNow.AddDays(7),
                signingCredentials: signingCredentials
                );
            return new JwtSecurityTokenHandler().WriteToken(token);

        }

You can find the whole project in my GitHub repo:https://github.com/ilkerkaran/simple-claim-based-auth

ilkerkaran
  • 4,214
  • 3
  • 27
  • 42