Skip to content

Commit 0a344f6

Browse files
author
Carlos Cañizares Estévez
committed
Improvements in identity, securice basket api, login-logout from mvc application and consume securiced basket.
1 parent a939fe7 commit 0a344f6

50 files changed

Lines changed: 4914 additions & 697 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docker-compose.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ services:
1414
ports:
1515
- "5100:80"
1616
depends_on:
17-
- catalog.api
1817
- identity.service
1918
- basket.api
2019

@@ -31,14 +30,13 @@ services:
3130
ports:
3231
- "5104:80"
3332
depends_on:
34-
- catalog.api
3533
- basket.api
3634
- identity.service
3735

3836
catalog.api:
3937
image: eshop/catalog.api
4038
environment:
41-
- ConnectionString=Server=catalog.data;Initial Catalog=CatalogData;User Id=sa;Password=Pass@word
39+
- ConnectionString=Server=catalog.data;Database=CatalogDB;User Id=sa;Password=Pass@word
4240
expose:
4341
- "80"
4442
ports:
@@ -77,6 +75,7 @@ services:
7775
image: eshop/identity
7876
environment:
7977
- Spa:http://webspa
78+
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers.WebMVC;User Id=sa;Password=Pass@word
8079
expose:
8180
- "80"
8281
ports:

src/Services/Basket/Basket.API/Controllers/BasketController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading.Tasks;
55
using Microsoft.AspNetCore.Mvc;
66
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
7+
using Microsoft.AspNetCore.Authorization;
78

89
namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
910
{
@@ -12,6 +13,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
1213
//If this is the case we should also investigate changing the serialization format used for Redis,
1314
//using a HashSet instead of a simple string.
1415
[Route("/")]
16+
[Authorize]
1517
public class BasketController : Controller
1618
{
1719
private IBasketRepository _repository;

src/Services/Basket/Basket.API/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static void Main(string[] args)
1717
.UseContentRoot(Directory.GetCurrentDirectory())
1818
.UseIISIntegration()
1919
.UseStartup<Startup>()
20+
.UseUrls("http://localhost:5008")
2021
.Build();
2122

2223
host.Run();

src/Services/Basket/Basket.API/Startup.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ public void ConfigureServices(IServiceCollection services)
4747
return ConnectionMultiplexer.Connect(ips.First().ToString());
4848
});
4949

50+
services.AddCors(options =>
51+
{
52+
options.AddPolicy("CorsPolicy",
53+
builder => builder.AllowAnyOrigin()
54+
.AllowAnyMethod()
55+
.AllowAnyHeader()
56+
.AllowCredentials());
57+
});
58+
5059
services.AddTransient<IBasketRepository, RedisBasketRepository>();
5160
}
5261

@@ -56,9 +65,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
5665
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
5766
loggerFactory.AddDebug();
5867

68+
// Use frameworks
69+
app.UseCors("CorsPolicy");
70+
5971
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
6072
{
61-
Authority = Configuration.GetValue("IdentityUrl", "http://localhost:5000"),
73+
Authority = "http://localhost:5000",
6274
ScopeName = "basket",
6375
RequireHttpsMetadata = false
6476
});

src/Services/Basket/Basket.API/appsettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
"Microsoft": "Information"
88
}
99
},
10-
"identityUrl": "http://localhost:5105",
10+
"identityUrl": "http://localhost:5000",
1111
"ConnectionString": "127.0.0.1"
1212
}

src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ public static IEnumerable<Client> GetClients()
4949
ClientName = "eShop SPA OpenId Client",
5050
AllowedGrantTypes = GrantTypes.Implicit,
5151
AllowAccessTokensViaBrowser = true,
52-
5352
RedirectUris = { "http://localhost:5003/callback.html" },
5453
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
5554
AllowedCorsOrigins = { "http://localhost:5003" },
56-
5755
AllowedScopes =
5856
{
5957
StandardScopes.OpenId.Name,
@@ -68,11 +66,9 @@ public static IEnumerable<Client> GetClients()
6866
ClientName = "eShop Xamarin OpenId Client",
6967
AllowedGrantTypes = GrantTypes.Implicit,
7068
AllowAccessTokensViaBrowser = true,
71-
7269
RedirectUris = { "http://localhost:5003/callback.html" },
7370
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
7471
AllowedCorsOrigins = { "http://localhost:5003" },
75-
7672
AllowedScopes =
7773
{
7874
StandardScopes.OpenId.Name,
@@ -90,9 +86,7 @@ public static IEnumerable<Client> GetClients()
9086
new Secret("secret".Sha256())
9187
},
9288
ClientUri = "http://localhost:2114",
93-
9489
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
95-
9690
RedirectUris = new List<string>
9791
{
9892
"http://localhost:2114/signin-oidc"

src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
using eShopOnContainers.Identity.Services;
2020
using eShopOnContainers.Identity.Models;
2121
using Microsoft.Extensions.Logging;
22+
using Microsoft.AspNetCore.Authorization;
23+
using eShopOnContainers.Identity.Models.AccountViewModels;
24+
using Microsoft.AspNetCore.Identity;
25+
using Microsoft.AspNetCore.Authentication;
2226

2327
namespace IdentityServer4.Quickstart.UI.Controllers
2428
{
@@ -34,19 +38,22 @@ public class AccountController : Controller
3438
private readonly IIdentityServerInteractionService _interaction;
3539
private readonly IClientStore _clientStore;
3640
private readonly ILogger _logger;
41+
private readonly UserManager<ApplicationUser> _userManager;
3742

3843
public AccountController(
3944

4045
//InMemoryUserLoginService loginService,
4146
ILoginService<ApplicationUser> loginService,
4247
IIdentityServerInteractionService interaction,
4348
IClientStore clientStore,
44-
ILoggerFactory loggerFactory)
49+
ILoggerFactory loggerFactory,
50+
UserManager<ApplicationUser> userManager)
4551
{
4652
_loginService = loginService;
4753
_interaction = interaction;
4854
_clientStore = clientStore;
4955
_logger = loggerFactory.CreateLogger<AccountController>();
56+
_userManager = userManager;
5057
}
5158

5259
/// <summary>
@@ -64,12 +71,6 @@ public async Task<IActionResult> Login(string returnUrl)
6471

6572
var vm = await BuildLoginViewModelAsync(returnUrl, context);
6673

67-
if (vm.EnableLocalLogin == false && vm.ExternalProviders.Count() == 1)
68-
{
69-
// only one option for logging in
70-
return ExternalLogin(vm.ExternalProviders.First().AuthenticationScheme, returnUrl);
71-
}
72-
7374
return View(vm);
7475
}
7576

@@ -78,11 +79,11 @@ public async Task<IActionResult> Login(string returnUrl)
7879
/// </summary>
7980
[HttpPost]
8081
[ValidateAntiForgeryToken]
81-
public async Task<IActionResult> Login(LoginInputModel model)
82+
public async Task<IActionResult> Login(LoginViewModel model)
8283
{
8384
if (ModelState.IsValid)
8485
{
85-
var user = await _loginService.FindByUsername(model.Username);
86+
var user = await _loginService.FindByUsername(model.Email);
8687
// validate username/password against in-memory store
8788
if (await _loginService.ValidateCredentials(user, model.Password))
8889
{
@@ -92,7 +93,7 @@ public async Task<IActionResult> Login(LoginInputModel model)
9293
AuthenticationProperties props = null;
9394
// only set explicit expiration here if persistent.
9495
// otherwise we reply upon expiration configured in cookie middleware.
95-
if (model.RememberLogin)
96+
if (model.RememberMe)
9697
{
9798
props = new AuthenticationProperties
9899
{
@@ -101,7 +102,6 @@ public async Task<IActionResult> Login(LoginInputModel model)
101102
};
102103
};
103104

104-
//await HttpContext.Authentication.SignInAsync(, user.UserName, props);
105105
await _loginService.SignIn(user);
106106

107107
// make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint
@@ -123,44 +123,29 @@ public async Task<IActionResult> Login(LoginInputModel model)
123123

124124
async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl, AuthorizationRequest context)
125125
{
126-
var providers = HttpContext.Authentication.GetAuthenticationSchemes()
127-
.Where(x => x.DisplayName != null)
128-
.Select(x => new ExternalProvider
129-
{
130-
DisplayName = x.DisplayName,
131-
AuthenticationScheme = x.AuthenticationScheme
132-
});
133-
134126
var allowLocal = true;
135127
if (context?.ClientId != null)
136128
{
137129
var client = await _clientStore.FindEnabledClientByIdAsync(context.ClientId);
138130
if (client != null)
139131
{
140132
allowLocal = client.EnableLocalLogin;
141-
142-
if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())
143-
{
144-
providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme));
145-
}
146133
}
147134
}
148135

149136
return new LoginViewModel
150137
{
151-
EnableLocalLogin = allowLocal,
152138
ReturnUrl = returnUrl,
153-
Username = context?.LoginHint,
154-
ExternalProviders = providers.ToArray()
139+
Email = context?.LoginHint,
155140
};
156141
}
157142

158-
async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)
143+
async Task<LoginViewModel> BuildLoginViewModelAsync(LoginViewModel model)
159144
{
160145
var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
161146
var vm = await BuildLoginViewModelAsync(model.ReturnUrl, context);
162-
vm.Username = model.Username;
163-
vm.RememberLogin = model.RememberLogin;
147+
vm.Email = model.Email;
148+
vm.RememberMe = model.RememberMe;
164149
return vm;
165150
}
166151

@@ -329,5 +314,62 @@ public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
329314

330315
return Redirect("~/");
331316
}
317+
318+
// GET: /Account/Register
319+
[HttpGet]
320+
[AllowAnonymous]
321+
public IActionResult Register(string returnUrl = null)
322+
{
323+
ViewData["ReturnUrl"] = returnUrl;
324+
return View();
325+
}
326+
327+
//
328+
// POST: /Account/Register
329+
[HttpPost]
330+
[AllowAnonymous]
331+
[ValidateAntiForgeryToken]
332+
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
333+
{
334+
ViewData["ReturnUrl"] = returnUrl;
335+
if (ModelState.IsValid)
336+
{
337+
var user = new ApplicationUser
338+
{
339+
UserName = model.Email,
340+
Email = model.Email,
341+
CardHolderName = model.User.CardHolderName,
342+
CardNumber = model.User.CardNumber,
343+
CardType = model.User.CardType,
344+
City = model.User.City,
345+
Country = model.User.Country,
346+
Expiration = model.User.Expiration,
347+
LastName = model.User.LastName,
348+
Name = model.User.Name,
349+
Street = model.User.Street,
350+
State = model.User.State,
351+
ZipCode = model.User.ZipCode,
352+
PhoneNumber = model.User.PhoneNumber,
353+
SecurityNumber = model.User.SecurityNumber
354+
};
355+
var result = await _userManager.CreateAsync(user, model.Password);
356+
if (result.Errors.Count() > 0)
357+
{
358+
AddErrors(result);
359+
// If we got this far, something failed, redisplay form
360+
return View(model);
361+
}
362+
}
363+
364+
return RedirectToAction("index", "home");
365+
}
366+
367+
private void AddErrors(IdentityResult result)
368+
{
369+
foreach (var error in result.Errors)
370+
{
371+
ModelState.AddModelError(string.Empty, error.Description);
372+
}
373+
}
332374
}
333375
}

src/Services/Identity/eShopOnContainers.Identity/Controllers/ConsentController.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using IdentityServer4.Models;
1111
using IdentityServer4.Stores;
1212
using IdentityServer4.Quickstart.UI.Models;
13+
using eShopOnContainers.Identity.Models.AccountViewModels;
1314

1415
namespace IdentityServer4.Quickstart.UI.Controllers
1516
{

src/Services/Identity/eShopOnContainers.Identity/Models/ConsentInputModel.cs renamed to src/Services/Identity/eShopOnContainers.Identity/Models/AccountViewModels/ConsentInputModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
using System.Collections.Generic;
66

7-
namespace IdentityServer4.Quickstart.UI.Models
7+
namespace eShopOnContainers.Identity.Models.AccountViewModels
88
{
99
public class ConsentInputModel
1010
{

src/Services/Identity/eShopOnContainers.Identity/Models/ConsentViewModel.cs renamed to src/Services/Identity/eShopOnContainers.Identity/Models/AccountViewModels/ConsentViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using System.Linq;
77
using IdentityServer4.Models;
88

9-
namespace IdentityServer4.Quickstart.UI.Models
9+
namespace eShopOnContainers.Identity.Models.AccountViewModels
1010
{
1111
public class ConsentViewModel : ConsentInputModel
1212
{

0 commit comments

Comments
 (0)