Browse Source

Merge from Master

pull/223/head
Ramón Tomás 7 years ago
parent
commit
2ad485015f
16 changed files with 126 additions and 35 deletions
  1. +13
    -13
      README.md
  2. BIN
      docs/Enterprise-Application-Patterns-using-XamarinForms.pdf
  3. BIN
      docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook).pdf
  4. BIN
      img/xamarin-enterprise-patterns-ebook-cover-small.png
  5. +6
    -6
      src/Mobile/README.md
  6. +7
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs
  7. +22
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Token/UserToken.cs
  8. +5
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IIdentityService.cs
  9. +22
    -5
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs
  10. +2
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/IRequestProvider.cs
  11. +33
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/RequestProvider.cs
  12. +8
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
  13. +4
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj
  14. +2
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/project.json
  15. +1
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj
  16. +1
    -1
      src/Services/Identity/Identity.API/Services/ProfileService.cs

+ 13
- 13
README.md View File

@ -3,20 +3,20 @@ Sample .NET Core reference application, powered by Microsoft, based on a simplif
**Note for Pull Requests**: We accept pull request from the community. When doing it, please do it onto the DEV branch which is the consolidated work-in-progress branch. Do not request it onto Master, if possible. **Note for Pull Requests**: We accept pull request from the community. When doing it, please do it onto the DEV branch which is the consolidated work-in-progress branch. Do not request it onto Master, if possible.
> ### DISCLAIMER > ### DISCLAIMER
> **IMPORTANT:** The current state of this sample application is **BETA**, consider it version a 0.1 foundational version, therefore, many areas could be improved and change significantly while refactoring current code and implementing new features. **Feedback with improvements and pull requests from the community will be highly appreciated and accepted.**
> **IMPORTANT:** The current state of this sample application is **BETA**, consider it version a 0.1 foundational version, therefore, many areas could be improved and change significantly while refactoring current code and implementing new features. **Feedback with improvements and pull requests from the community will be highly appreciated and accepted.**
> >
> This reference application proposes a simplified microservice oriented architecture implementation to introduce technologies like .NET Core with Docker containers through a comprehensive application. The chosen domain is an eShop/eCommerce but simply because it is a well-know domain by most people/developers. > This reference application proposes a simplified microservice oriented architecture implementation to introduce technologies like .NET Core with Docker containers through a comprehensive application. The chosen domain is an eShop/eCommerce but simply because it is a well-know domain by most people/developers.
However, this sample application should not be considered as an "eCommerce reference model", at all. The implemented business domain might not be ideal from an eCommerce business point of view. It is neither trying to solve all the problems in a large, scalable and mission-critical distributed system. It is just a bootstrap for developers to easily get started in the world of Docker containers and microservices with .NET Core.
> <p>For example, the next step (still not covered in eShopOnContainers) after understanding Docker containers and microservices development with .NET Core, is to select a microservice cluster/orchestrator like Docker Swarm, Kubernetes or DC/OS (in Azure Container Service) or Azure Service Fabric which in most of the cases will require additional partial changes to your application's configuration (although the present architecture should work on most orchestrators with small changes).
However, this sample application should not be considered as an "eCommerce reference model", at all. The implemented business domain might not be ideal from an eCommerce business point of view. It is neither trying to solve all the problems in a large, scalable and mission-critical distributed system. It is just a bootstrap for developers to easily get started in the world of Docker containers and microservices with .NET Core.
> <p>For example, the next step (still not covered in eShopOnContainers) after understanding Docker containers and microservices development with .NET Core, is to select a microservice cluster/orchestrator like Docker Swarm, Kubernetes or DC/OS (in Azure Container Service) or Azure Service Fabric which in most of the cases will require additional partial changes to your application's configuration (although the present architecture should work on most orchestrators with small changes).
> Additional steps would be to move your databases to HA cloud services, or to implement your EventBus with Azure Service Bus or any other production ready Service Bus in the market. > Additional steps would be to move your databases to HA cloud services, or to implement your EventBus with Azure Service Bus or any other production ready Service Bus in the market.
> <p> In the future we might fork this project and make multiple versions targeting specific microservice cluster/orchestrators plus using additional cloud infrastructure. <p> > <p> In the future we might fork this project and make multiple versions targeting specific microservice cluster/orchestrators plus using additional cloud infrastructure. <p>
> <img src="img/exploring-to-production-ready.png"> > <img src="img/exploring-to-production-ready.png">
> Read the planned <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>Roadmap and Milestones for future releases of eShopOnContainers</a> within the Wiki for further info about possible new implementations and provide feedback at the <a href='https://github.com/dotnet/eShopOnContainers/issues'>ISSUES section</a> if you'd like to see any specific scenario implemented or improved. Also, feel free to discuss on any current issue. > Read the planned <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>Roadmap and Milestones for future releases of eShopOnContainers</a> within the Wiki for further info about possible new implementations and provide feedback at the <a href='https://github.com/dotnet/eShopOnContainers/issues'>ISSUES section</a> if you'd like to see any specific scenario implemented or improved. Also, feel free to discuss on any current issue.
**Architecture overview**: This reference application is cross-platform either at the server and client side, thanks to .NET Core services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps.
The architecture proposes a simplified microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using Http as the current communication protocol.
**Architecture overview**: This reference application is cross-platform either at the server and client side, thanks to .NET Core services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps.
The architecture proposes a simplified microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using Http as the current communication protocol.
<p> <p>
It also supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus plus other features defined at the <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>roadmap</a>.
It also supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus plus other features defined at the <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>roadmap</a>.
<p> <p>
<img src="img/eshop_logo.png"> <img src="img/eshop_logo.png">
<img src="img/eShopOnContainers_Architecture_Diagram.png"> <img src="img/eShopOnContainers_Architecture_Diagram.png">
@ -43,7 +43,7 @@ You can download them and start reviewing these Guides/eBooks here:
| Architecting & Developing | Containers Lifecycle & CI/CD | App patterns with Xamarin.Forms | | Architecting & Developing | Containers Lifecycle & CI/CD | App patterns with Xamarin.Forms |
| ------------ | ------------| ------------| | ------------ | ------------| ------------|
| <a href='https://aka.ms/microservicesebook'><img src="img/ebook_arch_dev_microservices_containers_cover.png"> </a> | <a href='https://aka.ms/dockerlifecycleebook'> <img src="img/ebook_containers_lifecycle.png"> </a> | <a href='https://aka.ms/xamarinpatternsebook'> <img src="img/xamarin-enterprise-patterns-ebook-cover-small.png"> </a> | | <a href='https://aka.ms/microservicesebook'><img src="img/ebook_arch_dev_microservices_containers_cover.png"> </a> | <a href='https://aka.ms/dockerlifecycleebook'> <img src="img/ebook_containers_lifecycle.png"> </a> | <a href='https://aka.ms/xamarinpatternsebook'> <img src="img/xamarin-enterprise-patterns-ebook-cover-small.png"> </a> |
| <sup> <a href='https://aka.ms/microservicesebook'>**Download** (First Edition)</a> </sup> | <sup> <a href='https://aka.ms/dockerlifecycleebook'>**Download** (First Edition from late 2016) </a> </sup> | <sup> <a href='https://aka.ms/xamarinpatternsebook'>**Download** (Preview Edition) </a> </sup> |
| <sup> <a href='https://aka.ms/microservicesebook'>**Download** (First Edition)</a> </sup> | <sup> <a href='https://aka.ms/dockerlifecycleebook'>**Download** (First Edition from late 2016) </a> </sup> | <sup> <a href='https://aka.ms/xamarinpatternsebook'>**Download** (First Edition) </a> </sup> |
Send feedback to [dotnet-architecture-ebooks-feedback@service.microsoft.com](dotnet-architecture-ebooks-feedback@service.microsoft.com) Send feedback to [dotnet-architecture-ebooks-feedback@service.microsoft.com](dotnet-architecture-ebooks-feedback@service.microsoft.com)
<p> <p>
@ -66,7 +66,7 @@ Finally, those microservices are consumed by multiple client web and mobile apps
<b>*MVC Application (ASP.NET Core)*</b>: Its an MVC application where you can find interesting scenarios on how to consume HTTP-based microservices from C# running in the server side, as it is a typical ASP.NET Core MVC application. Since it is a server-side application, access to other containers/microservices is done within the internal Docker Host network with its internal name resolution. <b>*MVC Application (ASP.NET Core)*</b>: Its an MVC application where you can find interesting scenarios on how to consume HTTP-based microservices from C# running in the server side, as it is a typical ASP.NET Core MVC application. Since it is a server-side application, access to other containers/microservices is done within the internal Docker Host network with its internal name resolution.
<img src="img/eshop-webmvc-app-screenshot.png"> <img src="img/eshop-webmvc-app-screenshot.png">
<br> <br>
<b>*SPA (Single Page Application)*</b>: Providing similar "eShop business functionality" but developed with Angular 2, Typescript and slightly using ASP.NET Core MVC. This is another approach for client web applications to be used when you want to have a more modern client behavior which is not behaving with the typical browser round-trip on every action but behaving like a Single-Page-Application which is more similar to a desktop app usage experience. The consumption of the HTTP-based microservices is done from TypeScript/JavaScript in the client browser, so the client calls to the microservices come from out of the Docker Host internal network (Like from your network or even from the Internet).
<b>*SPA (Single Page Application)*</b>: Providing similar "eShop business functionality" but developed with Angular 2, Typescript and slightly using ASP.NET Core MVC. This is another approach for client web applications to be used when you want to have a more modern client behavior which is not behaving with the typical browser round-trip on every action but behaving like a Single-Page-Application which is more similar to a desktop app usage experience. The consumption of the HTTP-based microservices is done from TypeScript/JavaScript in the client browser, so the client calls to the microservices come from out of the Docker Host internal network (Like from your network or even from the Internet).
<img src="img/eshop-webspa-app-screenshot.png"> <img src="img/eshop-webspa-app-screenshot.png">
<br> <br>
<b>*Xamarin Mobile App (For iOS, Android and Windows/UWP)*</b>: It is a client mobile app supporting the most common mobile OS platforms (iOS, Android and Windows/UWP). In this case, the consumption of the microservices is done from C# but running on the client devices, so out of the Docker Host internal network (Like from your network or even the Internet). <b>*Xamarin Mobile App (For iOS, Android and Windows/UWP)*</b>: It is a client mobile app supporting the most common mobile OS platforms (iOS, Android and Windows/UWP). In this case, the consumption of the microservices is done from C# but running on the client devices, so out of the Docker Host internal network (Like from your network or even the Internet).
@ -76,19 +76,19 @@ Finally, those microservices are consumed by multiple client web and mobile apps
## Setting up your development environment for eShopOnContainers ## Setting up your development environment for eShopOnContainers
### Visual Studio 2017 and Windows based ### Visual Studio 2017 and Windows based
This is the more straightforward way to get started: This is the more straightforward way to get started:
https://github.com/dotnet/eShopOnContainers/wiki/02.-Setting-eShopOnContainer-solution-up-in-a-Visual-Studio-2017-environment
https://github.com/dotnet-architecture/eShopOnContainers/wiki/02.-Setting-eShopOnContainers-in-a-Visual-Studio-2017-environment
### CLI and Windows based ### CLI and Windows based
For those who prefer the CLI on Windows, using dotnet CLI, docker CLI and VS Code for Windows:
For those who prefer the CLI on Windows, using dotnet CLI, docker CLI and VS Code for Windows:
https://github.com/dotnet/eShopOnContainers/wiki/03.-Setting-the-eShopOnContainers-solution-up-in-a-Windows-CLI-environment-(dotnet-CLI,-Docker-CLI-and-VS-Code) https://github.com/dotnet/eShopOnContainers/wiki/03.-Setting-the-eShopOnContainers-solution-up-in-a-Windows-CLI-environment-(dotnet-CLI,-Docker-CLI-and-VS-Code)
### CLI and Mac based ### CLI and Mac based
For those who prefer the CLI on a Mac, using dotnet CLI, docker CLI and VS Code for Mac
For those who prefer the CLI on a Mac, using dotnet CLI, docker CLI and VS Code for Mac
(Instructions still TBD, but similar to Windows CLI): (Instructions still TBD, but similar to Windows CLI):
https://github.com/dotnet/eShopOnContainers/wiki/04.-Setting-eShopOnContainer-solution-up-in-a-Mac,-VS-Code-and-CLI-environment--(dotnet-CLI,-Docker-CLI-and-VS-Code) https://github.com/dotnet/eShopOnContainers/wiki/04.-Setting-eShopOnContainer-solution-up-in-a-Mac,-VS-Code-and-CLI-environment--(dotnet-CLI,-Docker-CLI-and-VS-Code)
> ### Note on tested Docker Containers/Images > ### Note on tested Docker Containers/Images
> Most of the development and testing of this project was (as of early March 2017) done <b> on Docker Linux containers</b> running in development machines with "Docker for Windows" and the default Hyper-V Linux VM (MobiLinuxVM) installed by "Docker for Windows".
> Most of the development and testing of this project was (as of early March 2017) done <b> on Docker Linux containers</b> running in development machines with "Docker for Windows" and the default Hyper-V Linux VM (MobiLinuxVM) installed by "Docker for Windows".
The <b>Windows Containers scenario is currently being implemented/tested yet</b>. The application should be able to run on Windows Nano Containers based on different Docker base images, as well, as the .NET Core services have also been tested running on plain Windows (with no Docker). The <b>Windows Containers scenario is currently being implemented/tested yet</b>. The application should be able to run on Windows Nano Containers based on different Docker base images, as well, as the .NET Core services have also been tested running on plain Windows (with no Docker).
The app was also partially tested on "Docker for Mac" using a development MacOS machine with .NET Core and VS Code installed, which is still a scenario using Linux containers running on the VM setup in the Mac by the "Docker for Windows" setup. But further testing and feedback on Mac environments and Windows Containers, from the community, will be appreciated. The app was also partially tested on "Docker for Mac" using a development MacOS machine with .NET Core and VS Code installed, which is still a scenario using Linux containers running on the VM setup in the Mac by the "Docker for Windows" setup. But further testing and feedback on Mac environments and Windows Containers, from the community, will be appreciated.
@ -118,4 +118,4 @@ You can create new issues at the issues section, do pull requests and/or send em
## Questions ## Questions
[QUESTION] Answer +1 if the solution is working for you (Through VS2017 or CLI environment): [QUESTION] Answer +1 if the solution is working for you (Through VS2017 or CLI environment):
https://github.com/dotnet/eShopOnContainers/issues/107
https://github.com/dotnet/eShopOnContainers/issues/107

BIN
docs/Enterprise-Application-Patterns-using-XamarinForms.pdf View File


BIN
docs/NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook).pdf View File


BIN
img/xamarin-enterprise-patterns-ebook-cover-small.png View File

Before After
Width: 260  |  Height: 336  |  Size: 25 KiB Width: 260  |  Height: 336  |  Size: 38 KiB

+ 6
- 6
src/Mobile/README.md View File

@ -1,12 +1,12 @@
#eShopOnContainers
# eShopOnContainers
eShopOnContainers is a reference app whose imagined purpose is to serve the mobile workforce of a fictitious company that sells products. The app allow to manage the catalog, view products, manage the basket and the orders. eShopOnContainers is a reference app whose imagined purpose is to serve the mobile workforce of a fictitious company that sells products. The app allow to manage the catalog, view products, manage the basket and the orders.
<img src="Images/eShopOnContainers_Architecture_Diagram.png" alt="eShopOnContainers" Width="800" /> <img src="Images/eShopOnContainers_Architecture_Diagram.png" alt="eShopOnContainers" Width="800" />
###Supported platforms: iOS, Android and Windows
### Supported platforms: iOS, Android and Windows
###The app architecture consists of two parts:
### The app architecture consists of two parts:
1. A Xamarin.Forms mobile app for iOS, Android and Windows. 1. A Xamarin.Forms mobile app for iOS, Android and Windows.
2. Several .NET Web API microservices deployed as Docker containers. 2. Several .NET Web API microservices deployed as Docker containers.
@ -34,7 +34,7 @@ This project exercises the following platforms, frameworks or features:
* Entity Framework * Entity Framework
* Identity Server 4 * Identity Server 4
##Three platforms
## Three platforms
The app targets **three** platforms: The app targets **three** platforms:
* iOS * iOS
@ -45,7 +45,7 @@ The app targets **three** platforms:
As of 07/03/2017, eShopOnContainers features **89.2% code share** (7.2% iOS / 16.7% Android / 8.7% Windows). As of 07/03/2017, eShopOnContainers features **89.2% code share** (7.2% iOS / 16.7% Android / 8.7% Windows).
##Licenses
## Licenses
This project uses some third-party assets with a license that requires attribution: This project uses some third-party assets with a license that requires attribution:
@ -155,4 +155,4 @@ In the configuration window of the machine, go to the Compatibility section and
<img src="Images/set-compatibility-vs-sml.png" alt="Migrate to a physical computer with a different processor version" Width="600" /> <img src="Images/set-compatibility-vs-sml.png" alt="Migrate to a physical computer with a different processor version" Width="600" />
## Copyright and license ## Copyright and license
* Code and documentation copyright 2017 Microsoft Corp. Code released under the [MIT license](https://opensource.org/licenses/MIT).
* Code and documentation copyright 2017 Microsoft Corp. Code released under the [MIT license](https://opensource.org/licenses/MIT).

+ 7
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs View File

@ -6,7 +6,6 @@
public const string MockTag = "Mock"; public const string MockTag = "Mock";
public const string DefaultEndpoint = "http://13.88.8.119"; public const string DefaultEndpoint = "http://13.88.8.119";
private string _baseEndpoint; private string _baseEndpoint;
private static readonly GlobalSetting _instance = new GlobalSetting(); private static readonly GlobalSetting _instance = new GlobalSetting();
@ -31,6 +30,10 @@
} }
} }
public string ClientId { get { return "xamarin"; }}
public string ClientSecret { get { return "secret"; }}
public string AuthToken { get; set; } public string AuthToken { get; set; }
public string RegisterWebsite { get; set; } public string RegisterWebsite { get; set; }
@ -47,6 +50,8 @@
public string UserInfoEndpoint { get; set; } public string UserInfoEndpoint { get; set; }
public string TokenEndpoint { get; set; }
public string LogoutEndpoint { get; set; } public string LogoutEndpoint { get; set; }
public string IdentityCallback { get; set; } public string IdentityCallback { get; set; }
@ -61,6 +66,7 @@
BasketEndpoint = string.Format("{0}:5103", baseEndpoint); BasketEndpoint = string.Format("{0}:5103", baseEndpoint);
IdentityEndpoint = string.Format("{0}:5105/connect/authorize", baseEndpoint); IdentityEndpoint = string.Format("{0}:5105/connect/authorize", baseEndpoint);
UserInfoEndpoint = string.Format("{0}:5105/connect/userinfo", baseEndpoint); UserInfoEndpoint = string.Format("{0}:5105/connect/userinfo", baseEndpoint);
TokenEndpoint = string.Format("{0}:5105/connect/token", baseEndpoint);
LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint); LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint);
IdentityCallback = string.Format("{0}:5105/xamarincallback", baseEndpoint); IdentityCallback = string.Format("{0}:5105/xamarincallback", baseEndpoint);
LogoutCallback = string.Format("{0}:5105/Account/Redirecting", baseEndpoint); LogoutCallback = string.Format("{0}:5105/Account/Redirecting", baseEndpoint);


+ 22
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Token/UserToken.cs View File

@ -0,0 +1,22 @@
using Newtonsoft.Json;
namespace eShopOnContainers.Core.Models.Token
{
public class UserToken
{
[JsonProperty("id_token")]
public string IdToken { get; set; }
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}
}

+ 5
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IIdentityService.cs View File

@ -1,8 +1,12 @@
namespace eShopOnContainers.Core.Services.Identity
using eShopOnContainers.Core.Models.Token;
using System.Threading.Tasks;
namespace eShopOnContainers.Core.Services.Identity
{ {
public interface IIdentityService public interface IIdentityService
{ {
string CreateAuthorizationRequest(); string CreateAuthorizationRequest();
string CreateLogoutRequest(string token); string CreateLogoutRequest(string token);
Task<UserToken> GetTokenAsync(string code);
} }
} }

+ 22
- 5
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs View File

@ -1,11 +1,22 @@
using IdentityModel.Client; using IdentityModel.Client;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using eShopOnContainers.Core.Services.RequestProvider;
using eShopOnContainers.Core.Models.Token;
namespace eShopOnContainers.Core.Services.Identity namespace eShopOnContainers.Core.Services.Identity
{ {
public class IdentityService : IIdentityService public class IdentityService : IIdentityService
{ {
private readonly IRequestProvider _requestProvider;
public IdentityService(IRequestProvider requestProvider)
{
_requestProvider = requestProvider;
}
public string CreateAuthorizationRequest() public string CreateAuthorizationRequest()
{ {
// Create URI to authorization endpoint // Create URI to authorization endpoint
@ -13,11 +24,10 @@ namespace eShopOnContainers.Core.Services.Identity
// Dictionary with values for the authorize request // Dictionary with values for the authorize request
var dic = new Dictionary<string, string>(); var dic = new Dictionary<string, string>();
dic.Add("client_id", "xamarin");
dic.Add("client_secret", "secret");
dic.Add("response_type", "code id_token token");
dic.Add("client_id", GlobalSetting.Instance.ClientId);
dic.Add("client_secret", GlobalSetting.Instance.ClientSecret);
dic.Add("response_type", "code id_token");
dic.Add("scope", "openid profile basket orders locations offline_access"); dic.Add("scope", "openid profile basket orders locations offline_access");
dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback); dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback);
dic.Add("nonce", Guid.NewGuid().ToString("N")); dic.Add("nonce", Guid.NewGuid().ToString("N"));
@ -31,7 +41,7 @@ namespace eShopOnContainers.Core.Services.Identity
public string CreateLogoutRequest(string token) public string CreateLogoutRequest(string token)
{ {
if(string.IsNullOrEmpty(token))
if (string.IsNullOrEmpty(token))
{ {
return string.Empty; return string.Empty;
} }
@ -41,5 +51,12 @@ namespace eShopOnContainers.Core.Services.Identity
token, token,
GlobalSetting.Instance.LogoutCallback); GlobalSetting.Instance.LogoutCallback);
} }
public async Task<UserToken> GetTokenAsync(string code)
{
string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}", code, WebUtility.UrlEncode(GlobalSetting.Instance.IdentityCallback));
var token = await _requestProvider.PostAsync<UserToken>(GlobalSetting.Instance.TokenEndpoint, data, GlobalSetting.Instance.ClientId, GlobalSetting.Instance.ClientSecret);
return token;
}
} }
} }

+ 2
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/IRequestProvider.cs View File

@ -8,6 +8,8 @@ namespace eShopOnContainers.Core.Services.RequestProvider
Task<TResult> PostAsync<TResult>(string uri, TResult data, string token = "", string header = ""); Task<TResult> PostAsync<TResult>(string uri, TResult data, string token = "", string header = "");
Task<TResult> PostAsync<TResult>(string uri, string data, string clientId, string clientSecret);
Task DeleteAsync(string uri, string token = ""); Task DeleteAsync(string uri, string token = "");
} }
} }

+ 33
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/RequestProvider.cs View File

@ -61,6 +61,28 @@ namespace eShopOnContainers.Core.Services.RequestProvider
return result; return result;
} }
public async Task<TResult> PostAsync<TResult>(string uri, string data, string clientId, string clientSecret)
{
HttpClient httpClient = CreateHttpClient(string.Empty);
if (!string.IsNullOrWhiteSpace(clientId) && !string.IsNullOrWhiteSpace(clientSecret))
{
AddBasicAuthenticationHeader(httpClient, clientId, clientSecret);
}
var content = new StringContent(data);
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.PostAsync(uri, content);
await HandleResponse(response);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = await Task.Run(() =>
JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));
return result;
}
public async Task DeleteAsync(string uri, string token = "") public async Task DeleteAsync(string uri, string token = "")
{ {
HttpClient httpClient = CreateHttpClient(token); HttpClient httpClient = CreateHttpClient(token);
@ -90,6 +112,17 @@ namespace eShopOnContainers.Core.Services.RequestProvider
httpClient.DefaultRequestHeaders.Add(parameter, Guid.NewGuid().ToString()); httpClient.DefaultRequestHeaders.Add(parameter, Guid.NewGuid().ToString());
} }
private void AddBasicAuthenticationHeader(HttpClient httpClient, string clientId, string clientSecret)
{
if (httpClient == null)
return;
if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret))
return;
httpClient.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(clientId, clientSecret);
}
private async Task HandleResponse(HttpResponseMessage response) private async Task HandleResponse(HttpResponseMessage response)
{ {
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)


+ 8
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs View File

@ -203,16 +203,15 @@ namespace eShopOnContainers.Core.ViewModels
private void Logout() private void Logout()
{ {
var authIdToken = Settings.AuthIdToken; var authIdToken = Settings.AuthIdToken;
var logoutRequest = _identityService.CreateLogoutRequest(authIdToken); var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);
if(!string.IsNullOrEmpty(logoutRequest))
if (!string.IsNullOrEmpty(logoutRequest))
{ {
// Logout // Logout
LoginUrl = logoutRequest; LoginUrl = logoutRequest;
} }
if(Settings.UseMocks)
if (Settings.UseMocks)
{ {
Settings.AuthAccessToken = string.Empty; Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty; Settings.AuthIdToken = string.Empty;
@ -235,12 +234,14 @@ namespace eShopOnContainers.Core.ViewModels
else if (unescapedUrl.Contains(GlobalSetting.Instance.IdentityCallback)) else if (unescapedUrl.Contains(GlobalSetting.Instance.IdentityCallback))
{ {
var authResponse = new AuthorizeResponse(url); var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.AccessToken))
if (!string.IsNullOrWhiteSpace(authResponse.Code))
{ {
if (authResponse.AccessToken != null)
var userToken = await _identityService.GetTokenAsync(authResponse.Code);
string accessToken = userToken.AccessToken;
if (!string.IsNullOrWhiteSpace(accessToken))
{ {
Settings.AuthAccessToken = authResponse.AccessToken;
Settings.AuthAccessToken = accessToken;
Settings.AuthIdToken = authResponse.IdentityToken; Settings.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync<MainViewModel>(); await NavigationService.NavigateToAsync<MainViewModel>();


+ 4
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj View File

@ -170,6 +170,7 @@
<Compile Include="Converters\FirstValidationErrorConverter.cs" /> <Compile Include="Converters\FirstValidationErrorConverter.cs" />
<Compile Include="Effects\EntryLineColorEffect.cs" /> <Compile Include="Effects\EntryLineColorEffect.cs" />
<Compile Include="Behaviors\LineColorBehavior.cs" /> <Compile Include="Behaviors\LineColorBehavior.cs" />
<Compile Include="Models\Token\UserToken.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
@ -263,6 +264,9 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Models\Token\" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System.ComponentModel.Annotations"> <Reference Include="System.ComponentModel.Annotations">
<HintPath>..\..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.6\Profile\Profile44\System.ComponentModel.Annotations.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.6\Profile\Profile44\System.ComponentModel.Annotations.dll</HintPath>


+ 2
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/project.json View File

@ -1,7 +1,8 @@
{ {
"dependencies": { "dependencies": {
"Xamarin.Forms": "2.3.4.231", "Xamarin.Forms": "2.3.4.231",
"xunit": "2.2.0"
"xunit": "2.2.0",
"xunit.runner.console": "2.2.0"
}, },
"frameworks": { "frameworks": {
".NETPortable,Version=v4.5,Profile=Profile111": {} ".NETPortable,Version=v4.5,Profile=Profile111": {}


+ 1
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj View File

@ -13,6 +13,7 @@
<AssemblyName>eShopOnContainersiOS</AssemblyName> <AssemblyName>eShopOnContainersiOS</AssemblyName>
<NuGetPackageImportStamp> <NuGetPackageImportStamp>
</NuGetPackageImportStamp> </NuGetPackageImportStamp>
<SkipValidatePackageReferences>true</SkipValidatePackageReferences>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>


+ 1
- 1
src/Services/Identity/Identity.API/Services/ProfileService.cs View File

@ -74,7 +74,7 @@ namespace Identity.API.Services
if (!string.IsNullOrWhiteSpace(user.Name)) if (!string.IsNullOrWhiteSpace(user.Name))
claims.Add(new Claim("name", user.Name)); claims.Add(new Claim("name", user.Name));
if (!string.IsNullOrWhiteSpace(user.Name))
if (!string.IsNullOrWhiteSpace(user.LastName))
claims.Add(new Claim("last_name", user.LastName)); claims.Add(new Claim("last_name", user.LastName));
if (!string.IsNullOrWhiteSpace(user.CardNumber)) if (!string.IsNullOrWhiteSpace(user.CardNumber))


Loading…
Cancel
Save