Docker Fix (#431)
* static added to Constants * Docker support for Blazor * GetHttp, PostHttp, ... inside AuthService, Docker working with login, Cookies Configuration temporary disabled * BaseAddress get web uri from Blazor Shared. * cookie options changed to fix docker. * Fixed returnUrl when inserting admin link and navigate without login * Functions not used removed. * AddPolicy using GetWebUrl * Login link removed from NavMenu * Change ConfigureCookieSettings, ConfigureCoreServices and ConfigureWebServices to be IServiceCollection extentions. * GetOriginWebUrl added. * Auto InDocker switch added. * Removed not used using .
This commit is contained in:
@@ -4,6 +4,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://+:80
|
- ASPNETCORE_URLS=http://+:80
|
||||||
|
- DOTNET_RUNNING_IN_CONTAINER=true
|
||||||
ports:
|
ports:
|
||||||
- "5106:80"
|
- "5106:80"
|
||||||
volumes:
|
volumes:
|
||||||
@@ -13,6 +14,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://+:80
|
- ASPNETCORE_URLS=http://+:80
|
||||||
|
- DOTNET_RUNNING_IN_CONTAINER=true
|
||||||
ports:
|
ports:
|
||||||
- "5200:80"
|
- "5200:80"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace BlazorAdmin
|
|
||||||
{
|
|
||||||
public class Constants
|
|
||||||
{
|
|
||||||
public const string API_URL = "https://localhost:5099/api/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
{
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<img class="col-md-6 esh-picture" src="@($"https://localhost:44315/{_item.PictureUri}")">
|
<img class="col-md-6 esh-picture" src="@($"{Auth.WebUrl}{_item.PictureUri}")">
|
||||||
|
|
||||||
<dl class="col-md-6 dl-horizontal">
|
<dl class="col-md-6 dl-horizontal">
|
||||||
<dt>
|
<dt>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
{
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<img class="col-md-6 esh-picture" src="@($"https://localhost:44315/{_item.PictureUri}")">
|
<img class="col-md-6 esh-picture" src="@($"{Auth.WebUrl}{_item.PictureUri}")">
|
||||||
|
|
||||||
<dl class="col-md-6 dl-horizontal">
|
<dl class="col-md-6 dl-horizontal">
|
||||||
<dt>
|
<dt>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
@page "/admin"
|
@page "/admin"
|
||||||
@attribute [Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS)]
|
@attribute [Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS)]
|
||||||
@inject AuthService Auth
|
@inject AuthService Auth
|
||||||
@using global::BlazorShared.Authorization
|
|
||||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ else
|
|||||||
{
|
{
|
||||||
<tr @onclick="@(() => DetailsClick(item.Id))">
|
<tr @onclick="@(() => DetailsClick(item.Id))">
|
||||||
<td>
|
<td>
|
||||||
<img class="img-thumbnail" src="@($"https://localhost:44315/{item.PictureUri}")">
|
<img class="img-thumbnail" src="@($"{Auth.WebUrl}{item.PictureUri}")">
|
||||||
</td>
|
</td>
|
||||||
<td>@Services.CatalogTypeServices.List.GetTypeName(catalogTypes, item.CatalogTypeId)</td>
|
<td>@Services.CatalogTypeServices.List.GetTypeName(catalogTypes, item.CatalogTypeId)</td>
|
||||||
<td>@Services.CatalogBrandServices.List.GetBrandName(catalogBrands, item.CatalogBrandId)</td>
|
<td>@Services.CatalogBrandServices.List.GetBrandName(catalogBrands, item.CatalogBrandId)</td>
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
using System;
|
using System.Net.Http;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BlazorAdmin.JavaScript;
|
using BlazorAdmin.JavaScript;
|
||||||
@@ -20,6 +16,12 @@ namespace BlazorAdmin.Services
|
|||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILocalStorageService _localStorage;
|
private readonly ILocalStorageService _localStorage;
|
||||||
private readonly IJSRuntime _jSRuntime;
|
private readonly IJSRuntime _jSRuntime;
|
||||||
|
|
||||||
|
public string ApiUrl => Constants.GetApiUrl(InDocker);
|
||||||
|
public string WebUrl => Constants.GetWebUrl(InDocker);
|
||||||
|
|
||||||
|
private static bool InDocker { get; set; }
|
||||||
|
|
||||||
public bool IsLoggedIn { get; set; }
|
public bool IsLoggedIn { get; set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
|
|
||||||
@@ -30,51 +32,33 @@ namespace BlazorAdmin.Services
|
|||||||
_jSRuntime = jSRuntime;
|
_jSRuntime = jSRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpClient GetHttpClient()
|
public async Task<HttpResponseMessage> HttpGet(string uri)
|
||||||
{
|
{
|
||||||
return _httpClient;
|
return await _httpClient.GetAsync($"{ApiUrl}{uri}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AuthResponse> LoginWithoutSaveToLocalStorage(AuthRequest user)
|
public async Task<HttpResponseMessage> HttpDelete(string uri, int id)
|
||||||
{
|
{
|
||||||
var jsonContent = new StringContent(JsonConvert.SerializeObject(user), Encoding.UTF8, "application/json");
|
return await _httpClient.DeleteAsync($"{ApiUrl}{uri}/{id}");
|
||||||
var response = await _httpClient.PostAsync($"{Constants.API_URL}authenticate", jsonContent);
|
|
||||||
var authResponse = new AuthResponse();
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
authResponse = await DeserializeToAuthResponse(response);
|
|
||||||
|
|
||||||
IsLoggedIn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return authResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AuthResponse> Login(AuthRequest user)
|
public async Task<HttpResponseMessage> HttpPost(string uri, object dataToSend)
|
||||||
{
|
{
|
||||||
var jsonContent = new StringContent(JsonConvert.SerializeObject(user), Encoding.UTF8, "application/json");
|
var content = ToJson(dataToSend);
|
||||||
var response = await _httpClient.PostAsync($"{Constants.API_URL}authenticate", jsonContent);
|
|
||||||
var authResponse = new AuthResponse();
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
return await _httpClient.PostAsync($"{ApiUrl}{uri}", content);
|
||||||
{
|
}
|
||||||
authResponse = await DeserializeToAuthResponse(response);
|
|
||||||
await SaveTokenInLocalStorage(authResponse);
|
|
||||||
await SaveUsernameInLocalStorage(authResponse);
|
|
||||||
await SetAuthorizationHeader();
|
|
||||||
|
|
||||||
UserName = await GetUsername();
|
public async Task<HttpResponseMessage> HttpPut(string uri, object dataToSend)
|
||||||
IsLoggedIn = true;
|
{
|
||||||
}
|
var content = ToJson(dataToSend);
|
||||||
|
|
||||||
return authResponse;
|
return await _httpClient.PutAsync($"{ApiUrl}{uri}", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Logout()
|
public async Task Logout()
|
||||||
{
|
{
|
||||||
await _localStorage.RemoveItemAsync("authToken");
|
await DeleteLocalStorage();
|
||||||
await _localStorage.RemoveItemAsync("username");
|
|
||||||
await DeleteCookies();
|
await DeleteCookies();
|
||||||
RemoveAuthorizationHeader();
|
RemoveAuthorizationHeader();
|
||||||
UserName = null;
|
UserName = null;
|
||||||
@@ -95,67 +79,11 @@ namespace BlazorAdmin.Services
|
|||||||
var username = await new Cookies(_jSRuntime).GetCookie("username");
|
var username = await new Cookies(_jSRuntime).GetCookie("username");
|
||||||
await SaveUsernameInLocalStorage(username);
|
await SaveUsernameInLocalStorage(username);
|
||||||
|
|
||||||
|
var inDocker = await new Cookies(_jSRuntime).GetCookie("inDocker");
|
||||||
|
await SaveInDockerInLocalStorage(inDocker);
|
||||||
|
|
||||||
await RefreshLoginInfo();
|
await RefreshLoginInfo();
|
||||||
}
|
}
|
||||||
private async Task LogoutIdentityManager()
|
|
||||||
{
|
|
||||||
await _httpClient.PostAsync("Identity/Account/Logout", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteCookies()
|
|
||||||
{
|
|
||||||
await new Cookies(_jSRuntime).DeleteCookie("token");
|
|
||||||
await new Cookies(_jSRuntime).DeleteCookie("username");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SetLoginData()
|
|
||||||
{
|
|
||||||
IsLoggedIn = !string.IsNullOrEmpty(await GetToken());
|
|
||||||
UserName = await GetUsername();
|
|
||||||
await SetAuthorizationHeader();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<AuthResponse> DeserializeToAuthResponse(HttpResponseMessage response)
|
|
||||||
{
|
|
||||||
var responseContent = await response.Content.ReadAsStringAsync();
|
|
||||||
return JsonConvert.DeserializeObject<AuthResponse>(responseContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveTokenInLocalStorage(AuthResponse authResponse)
|
|
||||||
{
|
|
||||||
await _localStorage.SetItemAsync("authToken", SaveTokenInLocalStorage(authResponse.Token));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveTokenInLocalStorage(string token)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(token))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await _localStorage.SetItemAsync("authToken", token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveAuthorizationHeader()
|
|
||||||
{
|
|
||||||
if (_httpClient.DefaultRequestHeaders.Contains("Authorization"))
|
|
||||||
{
|
|
||||||
_httpClient.DefaultRequestHeaders.Remove("Authorization");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveUsernameInLocalStorage(AuthResponse authResponse)
|
|
||||||
{
|
|
||||||
await _localStorage.SetItemAsync("username", SaveUsernameInLocalStorage(authResponse.Username));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveUsernameInLocalStorage(string username)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(username))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await _localStorage.SetItemAsync("username", username);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetToken()
|
public async Task<string> GetToken()
|
||||||
{
|
{
|
||||||
@@ -175,58 +103,83 @@ namespace BlazorAdmin.Services
|
|||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> GetInDocker()
|
||||||
|
{
|
||||||
|
return (await _localStorage.GetItemAsync<string>("inDocker")).ToLower() == "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringContent ToJson(object obj)
|
||||||
|
{
|
||||||
|
return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LogoutIdentityManager()
|
||||||
|
{
|
||||||
|
await _httpClient.PostAsync("Identity/Account/Logout", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteLocalStorage()
|
||||||
|
{
|
||||||
|
await _localStorage.RemoveItemAsync("authToken");
|
||||||
|
await _localStorage.RemoveItemAsync("username");
|
||||||
|
await _localStorage.RemoveItemAsync("inDocker");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteCookies()
|
||||||
|
{
|
||||||
|
await new Cookies(_jSRuntime).DeleteCookie("token");
|
||||||
|
await new Cookies(_jSRuntime).DeleteCookie("username");
|
||||||
|
await new Cookies(_jSRuntime).DeleteCookie("inDocker");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SetLoginData()
|
||||||
|
{
|
||||||
|
IsLoggedIn = !string.IsNullOrEmpty(await GetToken());
|
||||||
|
UserName = await GetUsername();
|
||||||
|
InDocker = await GetInDocker();
|
||||||
|
await SetAuthorizationHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveAuthorizationHeader()
|
||||||
|
{
|
||||||
|
if (_httpClient.DefaultRequestHeaders.Contains("Authorization"))
|
||||||
|
{
|
||||||
|
_httpClient.DefaultRequestHeaders.Remove("Authorization");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveTokenInLocalStorage(string token)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(token))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await _localStorage.SetItemAsync("authToken", token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveUsernameInLocalStorage(string username)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(username))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await _localStorage.SetItemAsync("username", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveInDockerInLocalStorage(string inDocker)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(inDocker))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await _localStorage.SetItemAsync("inDocker", inDocker);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SetAuthorizationHeader()
|
private async Task SetAuthorizationHeader()
|
||||||
{
|
{
|
||||||
var token = await GetToken();
|
var token = await GetToken();
|
||||||
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
|
|
||||||
{
|
|
||||||
var claims = new List<Claim>();
|
|
||||||
if (string.IsNullOrEmpty(jwt))
|
|
||||||
{
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload = jwt.Split('.')[1];
|
|
||||||
var jsonBytes = ParseBase64WithoutPadding(payload);
|
|
||||||
var keyValuePairs = JsonConvert.DeserializeObject<Dictionary<string, object>>(Encoding.UTF8.GetString(jsonBytes));
|
|
||||||
|
|
||||||
keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);
|
|
||||||
|
|
||||||
if (roles != null)
|
|
||||||
{
|
|
||||||
if (roles.ToString().Trim().StartsWith("["))
|
|
||||||
{
|
|
||||||
var parsedRoles = JsonConvert.DeserializeObject<string[]>(roles.ToString());
|
|
||||||
|
|
||||||
foreach (var parsedRole in parsedRoles)
|
|
||||||
{
|
|
||||||
claims.Add(new Claim(ClaimTypes.Role, parsedRole));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
claims.Add(new Claim(ClaimTypes.Role, roles.ToString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
keyValuePairs.Remove(ClaimTypes.Role);
|
|
||||||
}
|
|
||||||
|
|
||||||
claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString())));
|
|
||||||
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] ParseBase64WithoutPadding(string base64)
|
|
||||||
{
|
|
||||||
switch (base64.Length % 4)
|
|
||||||
{
|
|
||||||
case 2: base64 += "=="; break;
|
|
||||||
case 3: base64 += "="; break;
|
|
||||||
}
|
|
||||||
return Convert.FromBase64String(base64);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace BlazorAdmin.Services.CatalogBrandServices
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = (await _authService.GetHttpClient().GetAsync($"{Constants.API_URL}catalog-brands"));
|
var result = await _authService.HttpGet("catalog-brands");
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return brands;
|
return brands;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -19,9 +17,7 @@ namespace BlazorAdmin.Services.CatalogItemServices
|
|||||||
{
|
{
|
||||||
var catalogItemResult = new CatalogItem();
|
var catalogItemResult = new CatalogItem();
|
||||||
|
|
||||||
var content = new StringContent(JsonConvert.SerializeObject(catalogItem), Encoding.UTF8, "application/json");
|
var result = await _authService.HttpPost("catalog-items", catalogItem);
|
||||||
|
|
||||||
var result = await _authService.GetHttpClient().PostAsync($"{Constants.API_URL}catalog-items", content);
|
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return catalogItemResult;
|
return catalogItemResult;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace BlazorAdmin.Services.CatalogItemServices
|
|||||||
{
|
{
|
||||||
var catalogItemResult = string.Empty;
|
var catalogItemResult = string.Empty;
|
||||||
|
|
||||||
var result = await _authService.GetHttpClient().DeleteAsync($"{Constants.API_URL}catalog-items/{catalogItemId}");
|
var result = await _authService.HttpDelete("catalog-items", catalogItemId);
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return catalogItemResult;
|
return catalogItemResult;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -19,9 +17,7 @@ namespace BlazorAdmin.Services.CatalogItemServices
|
|||||||
{
|
{
|
||||||
var catalogItemResult = new CatalogItem();
|
var catalogItemResult = new CatalogItem();
|
||||||
|
|
||||||
var content = new StringContent(JsonConvert.SerializeObject(catalogItem), Encoding.UTF8, "application/json");
|
var result = await _authService.HttpPut("catalog-items", catalogItem);
|
||||||
|
|
||||||
var result = await _authService.GetHttpClient().PutAsync($"{Constants.API_URL}catalog-items", content);
|
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return catalogItemResult;
|
return catalogItemResult;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace BlazorAdmin.Services.CatalogItemServices
|
|||||||
{
|
{
|
||||||
var catalogItemResult = new CatalogItem();
|
var catalogItemResult = new CatalogItem();
|
||||||
|
|
||||||
var result = await _authService.GetHttpClient().GetAsync($"{Constants.API_URL}catalog-items/{catalogItemId}");
|
var result = await _authService.HttpGet($"catalog-items/{catalogItemId}");
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return catalogItemResult;
|
return catalogItemResult;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace BlazorAdmin.Services.CatalogItemServices
|
|||||||
{
|
{
|
||||||
var catalogItems = new List<CatalogItem>();
|
var catalogItems = new List<CatalogItem>();
|
||||||
|
|
||||||
var result = (await _authService.GetHttpClient().GetAsync($"{Constants.API_URL}catalog-items?PageSize={pageSize}"));
|
var result = await _authService.HttpGet($"catalog-items?PageSize={pageSize}");
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return catalogItems;
|
return catalogItems;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace BlazorAdmin.Services.CatalogTypeServices
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = (await _authService.GetHttpClient().GetAsync($"{Constants.API_URL}catalog-types"));
|
var result = await _authService.HttpGet("catalog-types");
|
||||||
if (result.StatusCode != HttpStatusCode.OK)
|
if (result.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
return types;
|
return types;
|
||||||
|
|||||||
@@ -27,12 +27,6 @@
|
|||||||
<span class="oi oi-account-logout" aria-hidden="true"></span> Logout
|
<span class="oi oi-account-logout" aria-hidden="true"></span> Logout
|
||||||
</NavLink>
|
</NavLink>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<NavLink class="nav-link" href="login">
|
|
||||||
<span class="oi oi-account-login" aria-hidden="true"></span> Login
|
|
||||||
</NavLink>
|
|
||||||
}
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"Identity/Account/Login?returnUrl=" +
|
Navigation.NavigateTo($"Identity/Account/Login?returnUrl=" +
|
||||||
Uri.EscapeDataString(Navigation.Uri));
|
$"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,11 +7,12 @@
|
|||||||
@using Microsoft.AspNetCore.Components.Web
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
@using Microsoft.AspNetCore.Components.WebAssembly.Http
|
@using Microsoft.AspNetCore.Components.WebAssembly.Http
|
||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
|
@using Microsoft.Extensions.Logging
|
||||||
@using BlazorAdmin
|
@using BlazorAdmin
|
||||||
@using BlazorAdmin.Shared
|
@using BlazorAdmin.Shared
|
||||||
@using BlazorAdmin.Services
|
@using BlazorAdmin.Services
|
||||||
@using BlazorAdmin.Services.CatalogBrandServices
|
@using BlazorAdmin.Services.CatalogBrandServices
|
||||||
@using BlazorAdmin.Services.CatalogItemServices
|
@using BlazorAdmin.Services.CatalogItemServices
|
||||||
@using BlazorAdmin.Services.CatalogTypeServices
|
@using BlazorAdmin.Services.CatalogTypeServices
|
||||||
@using Microsoft.Extensions.Logging
|
|
||||||
@using BlazorAdmin.JavaScript
|
@using BlazorAdmin.JavaScript
|
||||||
|
@using BlazorShared.Authorization
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
namespace BlazorShared.Authorization
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BlazorShared.Authorization
|
|
||||||
{
|
{
|
||||||
public class ClaimValue
|
public class ClaimValue
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +1,25 @@
|
|||||||
using System;
|
namespace BlazorShared.Authorization
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BlazorShared.Authorization
|
|
||||||
{
|
{
|
||||||
public class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public static class Roles
|
public static class Roles
|
||||||
{
|
{
|
||||||
public const string ADMINISTRATORS = "Administrators";
|
public const string ADMINISTRATORS = "Administrators";
|
||||||
}
|
}
|
||||||
|
public static string GetApiUrl(bool inDocker) =>
|
||||||
|
inDocker ? DOCKER_API_URL : API_URL;
|
||||||
|
|
||||||
|
public static string GetWebUrl(bool inDocker) =>
|
||||||
|
inDocker ? DOCKER_WEB_URL : WEB_URL;
|
||||||
|
|
||||||
|
public static string GetOriginWebUrl(bool inDocker) =>
|
||||||
|
GetWebUrl(inDocker).TrimEnd('/');
|
||||||
|
|
||||||
|
private const string API_URL = "https://localhost:5099/api/";
|
||||||
|
private const string DOCKER_API_URL = "http://localhost:5200/api/";
|
||||||
|
|
||||||
|
private const string WEB_URL = "https://localhost:44315/";
|
||||||
|
private const string DOCKER_WEB_URL = "http://localhost:5106/";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace BlazorShared.Authorization
|
namespace BlazorShared.Authorization
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using BlazorShared.Authorization;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@@ -28,6 +27,8 @@ namespace Microsoft.eShopWeb.PublicApi
|
|||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
private const string CORS_POLICY = "CorsPolicy";
|
private const string CORS_POLICY = "CorsPolicy";
|
||||||
|
public static bool InDocker => Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";
|
||||||
|
|
||||||
public Startup(IConfiguration configuration)
|
public Startup(IConfiguration configuration)
|
||||||
{
|
{
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
@@ -128,8 +129,7 @@ namespace Microsoft.eShopWeb.PublicApi
|
|||||||
{
|
{
|
||||||
builder.WithOrigins("http://localhost:44319",
|
builder.WithOrigins("http://localhost:44319",
|
||||||
"https://localhost:44319",
|
"https://localhost:44319",
|
||||||
"http://localhost:44315",
|
Constants.GetOriginWebUrl(InDocker));
|
||||||
"https://localhost:44315");
|
|
||||||
builder.AllowAnyMethod();
|
builder.AllowAnyMethod();
|
||||||
builder.AllowAnyHeader();
|
builder.AllowAnyHeader();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account
|
|||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
var token = await _tokenClaimsService.GetTokenAsync(Input.Email);
|
var token = await _tokenClaimsService.GetTokenAsync(Input.Email);
|
||||||
CreateAuthCookie(Input.Email, token);
|
CreateAuthCookie(Input.Email, token, Startup.InDocker);
|
||||||
_logger.LogInformation("User logged in.");
|
_logger.LogInformation("User logged in.");
|
||||||
await TransferAnonymousBasketToUserAsync(Input.Email);
|
await TransferAnonymousBasketToUserAsync(Input.Email);
|
||||||
return LocalRedirect(returnUrl);
|
return LocalRedirect(returnUrl);
|
||||||
@@ -114,12 +114,13 @@ namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account
|
|||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateAuthCookie(string username, string token)
|
private void CreateAuthCookie(string username, string token, bool inDocker)
|
||||||
{
|
{
|
||||||
var cookieOptions = new CookieOptions();
|
var cookieOptions = new CookieOptions();
|
||||||
cookieOptions.Expires = DateTime.Today.AddYears(10);
|
cookieOptions.Expires = DateTime.Today.AddYears(10);
|
||||||
Response.Cookies.Append("token", token, cookieOptions);
|
Response.Cookies.Append("token", token, cookieOptions);
|
||||||
Response.Cookies.Append("username", username, cookieOptions);
|
Response.Cookies.Append("username", username, cookieOptions);
|
||||||
|
Response.Cookies.Append("inDocker", inDocker.ToString(), cookieOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TransferAnonymousBasketToUserAsync(string userName)
|
private async Task TransferAnonymousBasketToUserAsync(string userName)
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ namespace Microsoft.eShopWeb.Web.Configuration
|
|||||||
{
|
{
|
||||||
public static class ConfigureCookieSettings
|
public static class ConfigureCookieSettings
|
||||||
{
|
{
|
||||||
public static void Configure(IServiceCollection services)
|
public static IServiceCollection AddCookieSettings(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.Configure<CookiePolicyOptions>(options =>
|
services.Configure<CookiePolicyOptions>(options =>
|
||||||
{
|
{
|
||||||
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
||||||
//TODO need to check that.
|
//TODO need to check that.
|
||||||
//options.CheckConsentNeeded = context => true;
|
//options.CheckConsentNeeded = context => true;
|
||||||
options.MinimumSameSitePolicy = SameSiteMode.None;
|
options.MinimumSameSitePolicy = SameSiteMode.Strict;
|
||||||
});
|
});
|
||||||
services.ConfigureApplicationCookie(options =>
|
services.ConfigureApplicationCookie(options =>
|
||||||
{
|
{
|
||||||
@@ -27,6 +27,8 @@ namespace Microsoft.eShopWeb.Web.Configuration
|
|||||||
IsEssential = true // required for auth to work without explicit user consent; adjust to suit your privacy policy
|
IsEssential = true // required for auth to work without explicit user consent; adjust to suit your privacy policy
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Microsoft.eShopWeb.Web.Configuration
|
|||||||
{
|
{
|
||||||
public static class ConfigureCoreServices
|
public static class ConfigureCoreServices
|
||||||
{
|
{
|
||||||
public static void Configure(IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddCoreServices(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>));
|
services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>));
|
||||||
services.AddScoped<IBasketService, BasketService>();
|
services.AddScoped<IBasketService, BasketService>();
|
||||||
@@ -19,6 +19,8 @@ namespace Microsoft.eShopWeb.Web.Configuration
|
|||||||
services.AddSingleton<IUriComposer>(new UriComposer(configuration.Get<CatalogSettings>()));
|
services.AddSingleton<IUriComposer>(new UriComposer(configuration.Get<CatalogSettings>()));
|
||||||
services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>));
|
services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>));
|
||||||
services.AddTransient<IEmailSender, EmailSender>();
|
services.AddTransient<IEmailSender, EmailSender>();
|
||||||
|
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Microsoft.eShopWeb.Web.Configuration
|
|||||||
{
|
{
|
||||||
public static class ConfigureWebServices
|
public static class ConfigureWebServices
|
||||||
{
|
{
|
||||||
public static void Configure(IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddWebServices(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddMediatR(typeof(BasketViewModelService).Assembly);
|
services.AddMediatR(typeof(BasketViewModelService).Assembly);
|
||||||
services.AddScoped<IBasketViewModelService, BasketViewModelService>();
|
services.AddScoped<IBasketViewModelService, BasketViewModelService>();
|
||||||
@@ -16,6 +16,8 @@ namespace Microsoft.eShopWeb.Web.Configuration
|
|||||||
services.AddScoped<ICatalogItemViewModelService, CatalogItemViewModelService>();
|
services.AddScoped<ICatalogItemViewModelService, CatalogItemViewModelService>();
|
||||||
services.Configure<CatalogSettings>(configuration);
|
services.Configure<CatalogSettings>(configuration);
|
||||||
services.AddScoped<ICatalogViewModelService, CachedCatalogViewModelService>();
|
services.AddScoped<ICatalogViewModelService, CachedCatalogViewModelService>();
|
||||||
|
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using BlazorAdmin.Services;
|
using BlazorAdmin.Services;
|
||||||
using Blazored.LocalStorage;
|
using Blazored.LocalStorage;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||||
|
|
||||||
namespace Microsoft.eShopWeb.Web
|
namespace Microsoft.eShopWeb.Web
|
||||||
@@ -30,6 +30,8 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
private IServiceCollection _services;
|
private IServiceCollection _services;
|
||||||
|
public static bool InDocker => Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";
|
||||||
|
|
||||||
public Startup(IConfiguration configuration)
|
public Startup(IConfiguration configuration)
|
||||||
{
|
{
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
@@ -83,7 +85,22 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
ConfigureCookieSettings.Configure(services);
|
services.AddCookieSettings();
|
||||||
|
|
||||||
|
if (InDocker)
|
||||||
|
{
|
||||||
|
services.AddDataProtection()
|
||||||
|
.SetApplicationName("eshopwebmvc")
|
||||||
|
.PersistKeysToFileSystem(new DirectoryInfo(@"./"));
|
||||||
|
}
|
||||||
|
|
||||||
|
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||||
|
.AddCookie(options =>
|
||||||
|
{
|
||||||
|
options.Cookie.HttpOnly = true;
|
||||||
|
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||||
|
options.Cookie.SameSite = SameSiteMode.Lax;
|
||||||
|
});
|
||||||
|
|
||||||
services.AddIdentity<ApplicationUser, IdentityRole>()
|
services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||||
.AddDefaultUI()
|
.AddDefaultUI()
|
||||||
@@ -92,8 +109,8 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
|
|
||||||
services.AddScoped<ITokenClaimsService, IdentityTokenClaimService>();
|
services.AddScoped<ITokenClaimsService, IdentityTokenClaimService>();
|
||||||
|
|
||||||
ConfigureCoreServices.Configure(services, Configuration);
|
services.AddCoreServices(Configuration);
|
||||||
ConfigureWebServices.Configure(services, Configuration);
|
services.AddWebServices(Configuration);
|
||||||
|
|
||||||
// Add memory cache services
|
// Add memory cache services
|
||||||
services.AddMemoryCache();
|
services.AddMemoryCache();
|
||||||
@@ -124,15 +141,9 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Blazor Admin Required Services for Prerendering
|
// Blazor Admin Required Services for Prerendering
|
||||||
services.AddScoped<HttpClient>(s =>
|
services.AddScoped<HttpClient>(s => new HttpClient
|
||||||
{
|
{
|
||||||
var navigationManager = s.GetRequiredService<NavigationManager>();
|
BaseAddress = new Uri(BlazorShared.Authorization.Constants.GetWebUrl(InDocker))
|
||||||
return new HttpClient
|
|
||||||
{
|
|
||||||
//TODO need to do it well
|
|
||||||
BaseAddress = new Uri("https://localhost:44315/")
|
|
||||||
//BaseAddress = new Uri(navigationManager.BaseUri)
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddBlazoredLocalStorage();
|
services.AddBlazoredLocalStorage();
|
||||||
@@ -197,6 +208,7 @@ namespace Microsoft.eShopWeb.Web
|
|||||||
endpoints.MapFallbackToFile("index.html");
|
endpoints.MapFallbackToFile("index.html");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user