Skip to content

Commit

Permalink
#218 - Starting with API project and JWT authentication.
Browse files Browse the repository at this point in the history
  • Loading branch information
maraf committed Feb 24, 2019
1 parent f3965ca commit 6e7dfb7
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 0 deletions.
19 changes: 19 additions & 0 deletions Money.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReadModels", "ReadModels",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{B38271C0-D03D-4DA3-97A5-7F2183CE7D15}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Money.Api", "src\Money.Api\Money.Api.csproj", "{D97DE048-58C6-4F5F-B042-6A70264AC8D0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -209,6 +211,22 @@ Global
{8D844524-F0FC-4DF7-9DF6-704327812309}.Release|x64.Build.0 = Release|Any CPU
{8D844524-F0FC-4DF7-9DF6-704327812309}.Release|x86.ActiveCfg = Release|Any CPU
{8D844524-F0FC-4DF7-9DF6-704327812309}.Release|x86.Build.0 = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|ARM.Build.0 = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|x64.ActiveCfg = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|x64.Build.0 = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|x86.ActiveCfg = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Debug|x86.Build.0 = Debug|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|Any CPU.Build.0 = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|ARM.ActiveCfg = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|ARM.Build.0 = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|x64.ActiveCfg = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|x64.Build.0 = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|x86.ActiveCfg = Release|Any CPU
{D97DE048-58C6-4F5F-B042-6A70264AC8D0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -221,6 +239,7 @@ Global
{DEBB89D5-7BA3-465C-B6D0-927FD61C0DFB} = {5F8D41B8-9780-4960-9071-3462BA179E23}
{E85307D8-DD3E-42C5-84F4-31A0A12AF37A} = {B38271C0-D03D-4DA3-97A5-7F2183CE7D15}
{F13BAE0F-446F-4E54-8DFD-63776E94D33D} = {B38271C0-D03D-4DA3-97A5-7F2183CE7D15}
{D97DE048-58C6-4F5F-B042-6A70264AC8D0} = {B38271C0-D03D-4DA3-97A5-7F2183CE7D15}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {71F1B232-0397-414E-8924-5802CD14E62B}
Expand Down
64 changes: 64 additions & 0 deletions src/Money.Api/Controllers/UserLoginController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Neptuo;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Money.Controllers
{
[Route("api/user/login")]
[ApiController]
public class UserLoginController : ControllerBase
{
public class LoginModel
{
public string UserName { get; set; }
public string Password { get; set; }
}

private readonly IConfiguration configuration;

public UserLoginController(IConfiguration configuration)
{
Ensure.NotNull(configuration, "configuration");
this.configuration = configuration.GetSection("Jwt");
}

[HttpPost]
public IActionResult Post([FromBody] LoginModel model)
{
if (model.UserName == "admin" && model.Password == "admin")
{
var claims = new[]
{
new Claim(ClaimTypes.Name, model.UserName)
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expiry = DateTime.Now.AddDays(Convert.ToInt32(configuration["ExpiryInDays"]));

var token = new JwtSecurityToken(
configuration["Issuer"],
configuration["Issuer"],
claims,
expires: expiry,
signingCredentials: creds
);

JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
string serializedToken = handler.WriteToken(token);

return base.Ok(new { token = serializedToken });
}

return BadRequest("Username and password are invalid.");
}
}
}
47 changes: 47 additions & 0 deletions src/Money.Api/Controllers/ValuesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Money.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}

// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}

// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}

// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}

// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
23 changes: 23 additions & 0 deletions src/Money.Api/Money.Api.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Neptuo\Neptuo.csproj" />
</ItemGroup>

<ItemGroup>
<Content Update="appsettings.Development.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>

</Project>
24 changes: 24 additions & 0 deletions src/Money.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Money.Api
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
30 changes: 30 additions & 0 deletions src/Money.Api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:63803",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Money.Api": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
70 changes: 70 additions & 0 deletions src/Money.Api/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;

namespace Money.Api
{
public class Startup
{
public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration) => Configuration = configuration;

public void ConfigureServices(IServiceCollection services)
{
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
IConfiguration jwtConfiguration = Configuration.GetSection("Jwt");

options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtConfiguration["Issuer"],
ValidAudience = jwtConfiguration["Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfiguration["SecurityKey"]))
};

options.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();

c.Response.StatusCode = 401;
c.Response.ContentType = "text/plain";

return c.Response.WriteAsync("There was an issue authorizing you.");
}
};
});

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseAuthentication();
app.UseMvc();
}
}
}
15 changes: 15 additions & 0 deletions src/Money.Api/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"Jwt": {
"SecurityKey": "abcdefghijklmnop",
"Issuer": "https://localhost",
"ExpiryInDays": 14
}
}
8 changes: 8 additions & 0 deletions src/Money.Api/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}

0 comments on commit 6e7dfb7

Please sign in to comment.