├── Images
├── mongodb.png
├── postmanok.png
├── postmantoken.png
└── postmanUnauthorized.png
├── .gitignore
├── Controllers
├── IHttpActionResult.cs
├── AuthController.cs
└── ProductController.cs
├── Model
├── Settings.cs
├── User.cs
└── Product.cs
├── rest.csproj.user
├── Infra
├── JwtSecurityKey.cs
├── JwtToken.cs
├── NoCacheAttribute.cs
└── JwtTokenBuilder.cs
├── Repository
├── Interface
│ ├── IAuthRepository.cs
│ └── IProductRepository.cs
├── AuthRepository.cs
└── ProductRepository.cs
├── appsettings.Development.json
├── appsettings.json
├── rest.csproj
├── Program.cs
├── Properties
└── launchSettings.json
├── Context
├── AuthContext.cs
└── ProductContext.cs
├── README.md
└── Startup.cs
/Images/mongodb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fabioono25/webapicore2jwt/HEAD/Images/mongodb.png
--------------------------------------------------------------------------------
/Images/postmanok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fabioono25/webapicore2jwt/HEAD/Images/postmanok.png
--------------------------------------------------------------------------------
/Images/postmantoken.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fabioono25/webapicore2jwt/HEAD/Images/postmantoken.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | /obj/
3 | /.vs/
4 | /.vscode/
5 | /obj
6 | /wwwroot
7 | .vs/config/applicationhost.config
--------------------------------------------------------------------------------
/Images/postmanUnauthorized.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fabioono25/webapicore2jwt/HEAD/Images/postmanUnauthorized.png
--------------------------------------------------------------------------------
/Controllers/IHttpActionResult.cs:
--------------------------------------------------------------------------------
1 | namespace rest.Controllers
2 | {
3 | internal interface IHttpActionResult
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/Model/Settings.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace rest.Model
3 | {
4 | public class Settings
5 | {
6 | public string ConnectionString;
7 | public string Database;
8 | }
9 | }
--------------------------------------------------------------------------------
/rest.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | IIS Express
5 |
6 |
--------------------------------------------------------------------------------
/Infra/JwtSecurityKey.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 | using Microsoft.IdentityModel.Tokens;
5 |
6 | namespace rest.Infra
7 | {
8 | public static class JwtSecurityKey
9 | {
10 | public static SymmetricSecurityKey Create(string secret)
11 | {
12 | return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret));
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Model/User.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 | using System.Collections.Generic;
4 | using MongoDB.Bson;
5 | using MongoDB.Bson.Serialization.Attributes;
6 |
7 | namespace rest.Model
8 | {
9 | public class User
10 | {
11 | [BsonId]
12 | public ObjectId Id { get; set; }
13 | public string Name { get; set; }
14 | public string Login { get; set; }
15 | public string Password { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/Repository/Interface/IAuthRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using MongoDB.Driver;
7 | using rest.Model;
8 |
9 | namespace rest.Repository.Interface
10 | {
11 | public interface IAuthRepository
12 | {
13 | Task> GetUsers();
14 |
15 | Task GetUser(string login, string password);
16 | }
17 | }
--------------------------------------------------------------------------------
/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Debug",
6 | "System": "Information",
7 | "Microsoft": "Information"
8 | }
9 | },
10 | "MongoConnection": {
11 | "ConnectionString": "mongodb://localhost:27017",
12 | "Database": "ProductDb"
13 | },
14 | "Authentication": {
15 | "Issuer": "issuerTest",
16 | "Audience": "bearerTest",
17 | "SecurityKey": "key-value-token-expires"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "Debug": {
5 | "LogLevel": {
6 | "Default": "Warning"
7 | }
8 | },
9 | "Console": {
10 | "LogLevel": {
11 | "Default": "Warning"
12 | }
13 | },
14 | "MongoConnection": {
15 | "ConnectionString": "mongodb://localhost:27017",
16 | "Database": "ProductDb"
17 | },
18 | "Authentication": {
19 | "Issuer": "issuerTest",
20 | "Audience": "bearerTest",
21 | "SecurityKey": "key-value-token-expires"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Infra/JwtToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IdentityModel.Tokens.Jwt;
3 | using System.Text;
4 | using Microsoft.AspNetCore.Mvc.Filters;
5 | using Microsoft.IdentityModel.Tokens;
6 |
7 | namespace rest.Infra
8 | {
9 | public sealed class JwtToken
10 | {
11 | private JwtSecurityToken token;
12 |
13 | internal JwtToken(JwtSecurityToken token)
14 | {
15 | this.token = token;
16 | }
17 |
18 | public DateTime ValidTo => token.ValidTo;
19 | public string Value => new JwtSecurityTokenHandler().WriteToken(this.token);
20 | }
21 | }
--------------------------------------------------------------------------------
/rest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Model/Product.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 | using System.Collections.Generic;
4 | using MongoDB.Bson;
5 | using MongoDB.Bson.Serialization.Attributes;
6 |
7 | namespace rest.Model
8 | {
9 | public class Product
10 | {
11 | [BsonId]
12 | public string Id { get; set; }
13 | public string Code { get; set; }
14 | public string Name { get; set; }
15 | public bool Active { get; set; }
16 | public string ImageUrl { get; set; }
17 | public string Description { get; set; }
18 | public DateTime CreatedOn { get; set; }
19 | public DateTime UpdatedOn { get; set; }
20 | }
21 | }
--------------------------------------------------------------------------------
/Infra/NoCacheAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Mvc.Filters;
3 |
4 | namespace rest.Infra
5 | {
6 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
7 | public sealed class NoCacheAttribute : ActionFilterAttribute
8 | {
9 | public override void OnResultExecuting(ResultExecutingContext context)
10 | {
11 | context.HttpContext.Response.Headers["Cache-Control"] = "no-cache, no-store, max-age=0";
12 | context.HttpContext.Response.Headers["Pragma"] = "no-cache";
13 | context.HttpContext.Response.Headers["Expires"] = "-1";
14 |
15 | base.OnResultExecuting(context);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Logging;
10 |
11 | namespace rest
12 | {
13 | public class Program
14 | {
15 | public static void Main(string[] args)
16 | {
17 | BuildWebHost(args).Run();
18 | }
19 |
20 | public static IWebHost BuildWebHost(string[] args) =>
21 | WebHost.CreateDefaultBuilder(args)
22 | .UseStartup()
23 | .Build();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:60757/",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "rest": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:60764/"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Repository/Interface/IProductRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using MongoDB.Driver;
7 | using rest.Model;
8 |
9 | namespace rest.Repository.Interface
10 | {
11 | public interface IProductRepository
12 | {
13 | Task> GetAllProducts();
14 | Task GetProduct(string id);
15 | Task AddProduct(Product item);
16 | Task RemoveProduct(string id);
17 | Task UpdateProduct(string id, Product product);
18 | Task UpdateProductDocument(string id, Product product);
19 | Task RemoveAllProducts();
20 | }
21 | }
--------------------------------------------------------------------------------
/Context/AuthContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.Extensions.Options;
7 | using MongoDB.Driver;
8 | using rest.Model;
9 |
10 | namespace rest.Context
11 | {
12 | public class AuthContext{
13 |
14 | private readonly IMongoDatabase _database = null;
15 |
16 | public AuthContext(IOptions settings)
17 | {
18 | var client = new MongoClient(settings.Value.ConnectionString);
19 | if (client != null)
20 | _database = client.GetDatabase(settings.Value.Database);
21 | }
22 |
23 | public IMongoCollection Users
24 | {
25 | get
26 | {
27 | return _database.GetCollection("User");
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Context/ProductContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.Extensions.Options;
7 | using MongoDB.Driver;
8 | using rest.Model;
9 |
10 | namespace rest.Context
11 | {
12 | public class ProductContext{
13 |
14 | private readonly IMongoDatabase _database = null;
15 |
16 | public ProductContext(IOptions settings)
17 | {
18 | var client = new MongoClient(settings.Value.ConnectionString);
19 | if (client != null)
20 | _database = client.GetDatabase(settings.Value.Database);
21 | }
22 |
23 | public IMongoCollection Products
24 | {
25 | get
26 | {
27 | return _database.GetCollection("Product");
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Repository/AuthRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.Extensions.Options;
7 | using MongoDB.Bson;
8 | using MongoDB.Driver;
9 | using rest.Context;
10 | using rest.Model;
11 | using rest.Repository.Interface;
12 |
13 | namespace rest.Repository
14 | {
15 | public class AuthRepository : IAuthRepository
16 | {
17 | private readonly AuthContext _context = null;
18 |
19 | public AuthRepository()
20 | {
21 | }
22 |
23 | public AuthRepository(IOptions settings)
24 | {
25 | _context = new AuthContext(settings);
26 | }
27 |
28 | public async Task> GetUsers()
29 | {
30 | var builder = Builders.Filter;
31 |
32 | return await _context.Users.Find(_ => true).ToListAsync();;
33 | }
34 |
35 | public async Task GetUser(string login, string password){
36 |
37 | var builder = Builders.Filter;
38 | var filter = builder.Eq("Login", login) & builder.Eq("Password", password);
39 |
40 | return await _context.Users
41 | .Find(filter)
42 | .FirstOrDefaultAsync();
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Controllers/AuthController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using MongoDB.Bson;
7 | using Newtonsoft.Json;
8 | using rest.Infra;
9 | using rest.Model;
10 | using rest.Repository.Interface;
11 |
12 | namespace rest.Controllers
13 | {
14 | [Produces("application/json")]
15 | [Route("api/[controller]")]
16 | public class AuthController : Controller, IHttpActionResult
17 | {
18 | private readonly IAuthRepository _AuthRepository;
19 |
20 | public AuthController(IAuthRepository AuthRepository)
21 | {
22 | _AuthRepository = AuthRepository;
23 | }
24 |
25 | // POST api/Auth
26 | [HttpPost]
27 | public async Task Create([FromBody]User user)
28 | {
29 | var usr = await _AuthRepository.GetUser(user.Login, user.Password);
30 |
31 | if (usr != null){
32 |
33 | var token = new JwtTokenBuilder()
34 | .AddSecurityKey(JwtSecurityKey.Create("key-value-token-expires"))
35 | .AddSubject(user.Login)
36 | .AddIssuer("issuerTest")
37 | .AddAudience("bearerTest")
38 | .AddClaim("MembershipId", "111")
39 | .AddExpiry(1)
40 | .Build();
41 |
42 | return Ok(token.Value);
43 |
44 | }else
45 | return Unauthorized();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Controllers/ProductController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Authorization;
6 | using Microsoft.AspNetCore.Mvc;
7 | using MongoDB.Bson;
8 | using Newtonsoft.Json;
9 | using rest.Infra;
10 | using rest.Model;
11 | using rest.Repository.Interface;
12 |
13 | namespace rest.Controllers
14 | {
15 | [Authorize(Policy = "Member")]
16 | [Produces("application/json")]
17 | [Route("api/[controller]")]
18 | public class ProductsController : Controller
19 | {
20 | private readonly IProductRepository _ProductRepository;
21 |
22 | public ProductsController(IProductRepository ProductRepository)
23 | {
24 | _ProductRepository = ProductRepository;
25 | }
26 |
27 | [NoCache]
28 | [HttpGet]
29 | public Task> Get()
30 | {
31 | return GetProductInternal();
32 | }
33 |
34 | private async Task> GetProductInternal()
35 | {
36 | return await _ProductRepository.GetAllProducts();
37 | }
38 |
39 | // GET api/Products/5
40 | [HttpGet("{id}")]
41 | public Task Get(string id)
42 | {
43 | return GetProductByIdInternal(id);
44 | }
45 |
46 | private async Task GetProductByIdInternal(string id)
47 | {
48 | return await _ProductRepository.GetProduct(id) ?? new Product();
49 | }
50 |
51 | // POST api/Products
52 | [HttpPost]
53 | public void Post([FromBody]Product product)
54 | {
55 | _ProductRepository.AddProduct(new Product()
56 | { Id = ObjectId.GenerateNewId().ToString(),
57 | Name = product.Name,
58 | Code = product.Code,
59 | Active = true,
60 | Description = product.Description,
61 | ImageUrl = product.ImageUrl,
62 | CreatedOn = DateTime.Now,
63 | UpdatedOn = DateTime.Now
64 | });
65 | }
66 |
67 | // PUT api/Products/5
68 | [HttpPut("{id}")]
69 | public void Put(string id, [FromBody]Product product)
70 | {
71 | _ProductRepository.UpdateProductDocument(id, product);
72 | }
73 |
74 | // DELETE api/Products/23243423
75 | [HttpDelete("{id}")]
76 | public void Delete(string id)
77 | {
78 | _ProductRepository.RemoveProduct(id);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Repository/ProductRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.Extensions.Options;
7 | using MongoDB.Bson;
8 | using MongoDB.Driver;
9 | using rest.Context;
10 | using rest.Model;
11 |
12 | namespace rest.Repository.Interface
13 | {
14 | public class ProductRepository : IProductRepository
15 | {
16 | private readonly ProductContext _context = null;
17 |
18 | public ProductRepository()
19 | {
20 | }
21 |
22 | public ProductRepository(IOptions settings)
23 | {
24 | _context = new ProductContext(settings);
25 | }
26 |
27 | public async Task AddProduct(Product item)
28 | {
29 | await _context.Products.InsertOneAsync(item);
30 | }
31 |
32 | public async Task> GetAllProducts()
33 | {
34 | return await _context.Products.Find(_ => true).ToListAsync();
35 | }
36 |
37 | public async Task GetProduct(string id)
38 | {
39 | var filter = Builders.Filter.Eq("Id", id);
40 | return await _context.Products
41 | .Find(filter)
42 | .FirstOrDefaultAsync();
43 | }
44 |
45 | public async Task RemoveAllProducts()
46 | {
47 | return await _context.Products.DeleteManyAsync(new BsonDocument());
48 | }
49 |
50 | public async Task RemoveProduct(string id)
51 | {
52 | return await _context.Products.DeleteOneAsync(
53 | Builders.Filter.Eq("Id", id));
54 | }
55 |
56 | public async Task UpdateProduct(string id, Product item)
57 | {
58 | try
59 | {
60 | return await _context.Products
61 | .ReplaceOneAsync(n => n.Id.Equals(id)
62 | , item
63 | , new UpdateOptions { IsUpsert = true });
64 | }
65 | catch (Exception ex)
66 | {
67 | // log or manage the exception
68 | throw ex;
69 | }
70 | }
71 |
72 | public async Task UpdateProductDocument(string id, Product product)
73 | {
74 | var item = await GetProduct(id) ?? new Product();
75 | item.Active = product.Active;
76 | item.Code = product.Code;
77 | item.Name = product.Name;
78 | item.UpdatedOn = DateTime.Now;
79 |
80 | return await UpdateProduct(id, item);
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/Infra/JwtTokenBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IdentityModel.Tokens.Jwt;
4 | using System.Linq;
5 | using System.Security.Claims;
6 | using System.Text;
7 | using Microsoft.AspNetCore.Mvc.Filters;
8 | using Microsoft.IdentityModel.Tokens;
9 |
10 | namespace rest.Infra
11 | {
12 | public sealed class JwtTokenBuilder
13 | {
14 | private SecurityKey securityKey = null;
15 | private string subject = "";
16 | private string issuer = "";
17 | private string audience = "";
18 | private Dictionary claims = new Dictionary();
19 | private int expiryInMinutes = 5;
20 |
21 | public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey)
22 | {
23 | this.securityKey = securityKey;
24 | return this;
25 | }
26 |
27 | public JwtTokenBuilder AddSubject(string subject)
28 | {
29 | this.subject = subject;
30 | return this;
31 | }
32 |
33 | public JwtTokenBuilder AddIssuer(string issuer)
34 | {
35 | this.issuer = issuer;
36 | return this;
37 | }
38 |
39 | public JwtTokenBuilder AddAudience(string audience)
40 | {
41 | this.audience = audience;
42 | return this;
43 | }
44 |
45 | public JwtTokenBuilder AddClaim(string type, string value)
46 | {
47 | this.claims.Add(type, value);
48 | return this;
49 | }
50 |
51 | public JwtTokenBuilder AddClaims(Dictionary claims)
52 | {
53 | this.claims.Union(claims);
54 | return this;
55 | }
56 |
57 | public JwtTokenBuilder AddExpiry(int expiryInMinutes)
58 | {
59 | this.expiryInMinutes = expiryInMinutes;
60 | return this;
61 | }
62 |
63 | public JwtToken Build()
64 | {
65 | EnsureArguments();
66 |
67 | var claims = new List
68 | {
69 | new Claim(JwtRegisteredClaimNames.Sub, this.subject),
70 | new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
71 | }
72 | .Union(this.claims.Select(item => new Claim(item.Key, item.Value)));
73 |
74 | var token = new JwtSecurityToken(
75 | issuer: this.issuer,
76 | audience: this.audience,
77 | claims: claims,
78 | expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
79 | signingCredentials: new SigningCredentials(
80 | this.securityKey,
81 | SecurityAlgorithms.HmacSha256));
82 |
83 | return new JwtToken(token);
84 | }
85 |
86 | #region " private "
87 |
88 | private void EnsureArguments()
89 | {
90 | if (this.securityKey == null)
91 | throw new ArgumentNullException("Security Key");
92 |
93 | if (string.IsNullOrEmpty(this.subject))
94 | throw new ArgumentNullException("Subject");
95 |
96 | if (string.IsNullOrEmpty(this.issuer))
97 | throw new ArgumentNullException("Issuer");
98 |
99 | if (string.IsNullOrEmpty(this.audience))
100 | throw new ArgumentNullException("Audience");
101 | }
102 |
103 | #endregion
104 | }
105 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Example of REST API Using MongoDB, .NET Core 2.0 and JWT Authentication
2 |
3 | ### Technologies:
4 |
5 | - .NET Core 2.0;
6 | - MongoDB;
7 | - JWT Authentication.
8 |
9 | ### Running this solution:
10 |
11 | First download or clone the project in a local directory:
12 |
13 | Then you must create a local or cloud MongoDB instance. In this instance, it's necessary the creation of a **ProductDb**
14 | database and two collections, **Product** and **User**. You can use this commands bellow so you can incluse the user:
15 |
16 | ```javascript
17 | db.User.insert({"Name": "Joao Teste", "Login": "joao", "Password": "1234"})
18 | ```
19 |
20 | 
21 |
22 | It's necessary to configure **appsettings.Development.json** with your instance of MongoDB:
23 |
24 | ```javascript
25 | "ConnectionString": "mongodb://localhost:27017",
26 | ```
27 |
28 | Next, you can open you project in Visual Studio or Visual Studio Code. You can type these two commands (to restore nuget package components and run the API):
29 |
30 | ```mongodb
31 | dotnet restore
32 | ```
33 |
34 | ```javascript
35 | dotnet run
36 | ```
37 |
38 | Now, if everything is all right, your API will be working. You must run the command bellow so you can create as authentication token:
39 |
40 | ```javascript
41 | http://localhost:5000/api/Auth
42 | ```
43 |
44 | Remember: it's necessary define **user** and **password** in payload:
45 |
46 | ```javascript
47 | {
48 | "Login": "joao",
49 | "Password": "1234"
50 | }
51 | ```
52 |
53 | The result is like this:
54 |
55 | 
56 |
57 | You must use this token so you can use GET, POST, PUT, DELETE verbs. For every of these REST verbs, you must put the generated token in **Authorization Header**, with the word **Bearer** like this:
58 |
59 | ```javascript
60 | Header: Authorization
61 | Value: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2FvIiwianRpIjoiMTFlYWFlODMtZTA4NS00NjA1LTlhNGQtZWI5ZjEzZjdhMDk5IiwiTWVtYmVyc2hpcElkIjoiMTExIiwiZXhwIjoxNTEwMTk0NjQ5LCJpc3MiOiJpc3N1ZXJUZXN0IiwiYXVkIjoiYmVhcmVyVGVzdCJ9.mN3uPfdK19xeMbOoeFfhtuFSpXrGUZ7eR6muM7Nz_fo
62 | ```
63 |
64 | To use POST, so you can insert some Products, use this URL bellow:
65 |
66 | ```javascript
67 | http://localhost:5000/api/Products
68 | ```
69 |
70 | With this payloads:
71 |
72 | ```javascript
73 | {
74 | "Code": "COD1",
75 | "Name": "Produto 1",
76 | "Active": true,
77 | "ImageUrl": "http://download.gamezone.com/uploads/image/data/1102202/League_of_Legends_Rune_Wars_Renekton.jpg",
78 | "Description": "Descrição do Produto 1"
79 | }
80 | ```
81 | ```javascript
82 | {
83 | "Code": "COD2",
84 | "Name": "Produto 2",
85 | "Active": true,
86 | "ImageUrl": "http://images.nintendolife.com/news/2014/08/weirdness_yoshis_real_name_is_both_silly_and_scientific/attachment/0/900x.jpg",
87 | "Description": "Descrição do Produto 2"
88 | }
89 | ```
90 | ```javascript
91 | {
92 | "Code": "COD3",
93 | "Name": "Produto 3",
94 | "Active": true,
95 | "ImageUrl": "http://da-v4-mbl.digitalbrandsinc.netdna-cdn.com/wp-content/uploads/2012/08/snails-612x320.jpg",
96 | "Description": "Descrição do Produto 3"
97 | }
98 | ```
99 |
100 | Now you can list the products inserted. Use this URL:
101 |
102 | ```javascript
103 | https://github.com/fabioono25/webapicore2jwt/blob/master/Images/postmanok.png
104 | ```
105 |
106 | 
107 |
108 |
109 | Remember, we are using a JWT Token Authentication. The definition of the expiration is 1 minute. Because of this, you maybe get **Error 401 - Unauthorized**. It's perfectly normal:
110 |
111 |
112 | 
113 |
114 | You just generate another token and put it on Header Authorization.
115 |
116 |
117 |
--------------------------------------------------------------------------------
/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Authentication.JwtBearer;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using Microsoft.Extensions.Options;
12 | using Microsoft.IdentityModel.Tokens;
13 | using rest.Infra;
14 | using rest.Model;
15 | using rest.Repository;
16 | using rest.Repository.Interface;
17 |
18 | namespace rest
19 | {
20 | public class Startup
21 | {
22 | public Startup(IConfiguration configuration)
23 | {
24 | Configuration = configuration;
25 | }
26 |
27 | public IConfiguration Configuration { get; }
28 |
29 | // This method gets called by the runtime. Use this method to add services to the container.
30 | public void ConfigureServices(IServiceCollection services)
31 | {
32 | services.AddCors(options =>
33 | {
34 | options.AddPolicy("CorsPolicy",
35 | builder => builder.AllowAnyOrigin()
36 | .AllowAnyMethod()
37 | .AllowAnyHeader()
38 | .AllowCredentials());
39 | });
40 |
41 | //services.AddCors();
42 |
43 | services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
44 | .AddJwtBearer(options => {
45 | options.TokenValidationParameters = new TokenValidationParameters
46 | {
47 | ValidateIssuer = true,
48 | ValidateAudience = true,
49 | ValidateLifetime = true,
50 | ValidateIssuerSigningKey = true,
51 |
52 | ValidIssuer = Configuration.GetSection("Authentication:Issuer").Value,
53 | ValidAudience = Configuration.GetSection("Authentication:Audience").Value,
54 | IssuerSigningKey = JwtSecurityKey.Create(Configuration.GetSection("Authentication:SecurityKey").Value)
55 | };
56 |
57 | options.Events = new JwtBearerEvents
58 | {
59 | OnAuthenticationFailed = context =>
60 | {
61 | Console.WriteLine("OnAuthenticationFailed: " + context.Exception.Message);
62 | return Task.CompletedTask;
63 | },
64 | OnTokenValidated = context =>
65 | {
66 | Console.WriteLine("OnTokenValidated: " + context.SecurityToken);
67 | return Task.CompletedTask;
68 | }
69 | };
70 | });
71 |
72 | services.AddAuthorization(options =>
73 | {
74 | options.AddPolicy("Member",
75 | policy => policy.RequireClaim("MembershipId"));
76 | });
77 |
78 | services.AddMvc();
79 |
80 | services.Configure(options =>
81 | {
82 | options.ConnectionString = Configuration.GetSection("MongoConnection:ConnectionString").Value;
83 | options.Database = Configuration.GetSection("MongoConnection:Database").Value;
84 | });
85 |
86 | services.AddTransient();
87 | services.AddTransient();
88 |
89 | }
90 |
91 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
92 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
93 | {
94 | // if (env.IsDevelopment())
95 | // {
96 | // app.UseDeveloperExceptionPage();
97 | // }
98 |
99 | app.UseCors("CorsPolicy");
100 | app.UseDeveloperExceptionPage();
101 | app.UseStaticFiles();
102 | app.UseAuthentication();
103 | app.UseMvcWithDefaultRoute();
104 |
105 | app.UseMvc();
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------