Skip to content

Commit

Permalink
Registering with an OpenID provider, adding OpenID configuration, con…
Browse files Browse the repository at this point in the history
…figuring services and middleware, marking controllers, actions and page code-behind to use authorization
  • Loading branch information
gorohoroh committed Jul 14, 2018
1 parent f846341 commit 170462e
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 4 deletions.
3 changes: 3 additions & 0 deletions OdeToFoodRider/OdeToFoodRider/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OdeToFoodRider.Models;
using OdeToFoodRider.Services;
using OdeToFoodRider.ViewModels;

namespace OdeToFoodRider.Controllers
{
[Authorize]
public class HomeController : Controller
{
// VSRD: This time, "Initialize field from constructor" does exactly what we want.
Expand All @@ -19,6 +21,7 @@ public HomeController(IRestaurantData restaurantData, IGreeter greeter)
}


[AllowAnonymous]
public IActionResult Index()
{
// VSRD: "Use object initialization" available in both IDEs but in Visual Studio, it's only available on the constructor call, not on further variable usages.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using OdeToFoodRider.Models;
using OdeToFoodRider.Services;

namespace OdeToFoodRider.Pages.Restaurants
{
[Authorize]
public class EditModel : PageModel
{
private readonly IRestaurantData _restaurantData;
Expand Down
1 change: 1 addition & 0 deletions OdeToFoodRider/OdeToFoodRider/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public static void Main(string[] args)
.AddEnvironmentVariables()
.AddJsonFile("certificate.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile("github.json", optional: false, reloadOnChange: true)
.Build();

var certificateSettings = config.GetSection("certificateSettings");
Expand Down
51 changes: 51 additions & 0 deletions OdeToFoodRider/OdeToFoodRider/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
Expand All @@ -12,6 +18,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using OdeToFoodRider.Data;
using OdeToFoodRider.Services;

Expand All @@ -30,6 +37,49 @@ public Startup(IConfiguration configuration)
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "GitHub";
})
.AddCookie()
.AddOAuth("GitHub", options =>
{
options.ClientId = _configuration.GetSection("GitHub").GetValue<string>("ClientId");
options.ClientSecret = _configuration.GetSection("GitHub").GetValue<string>("ClientSecret");
options.CallbackPath = new PathString("/signin-oidc");
options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
options.TokenEndpoint = "https://github.com/login/oauth/access_token";
options.UserInformationEndpoint = "https://api.github.com/user";
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
options.ClaimActions.MapJsonKey("urn:github:login", "login");
options.ClaimActions.MapJsonKey("urn:github:url", "html_url");
options.ClaimActions.MapJsonKey("urn:github:avatar", "avatar_url");
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JObject.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user);
}
};
})
;
services.AddSingleton<IGreeter, Greeter>();
services.AddDbContext<OdeToFoodDbContext>(options =>
options.UseSqlServer(_configuration.GetConnectionString("OdeToFood")));
Expand Down Expand Up @@ -58,6 +108,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, IGreeter

app.UseRewriter(new RewriteOptions().AddRedirectToHttpsPermanent());
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(ConfigureRoutes);

app.Run(async (context) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OdeToFoodVisualStudio.Models;
using OdeToFoodVisualStudio.Services;
using OdeToFoodVisualStudio.ViewModels;

namespace OdeToFoodVisualStudio.Controllers
{
[Authorize]
public class HomeController : Controller
{
private IRestaurantData _restaurantData;
Expand All @@ -21,6 +23,7 @@ public HomeController(IRestaurantData restaurantData, IGreeter greeter)
_greeter = greeter;
}

[AllowAnonymous]
public IActionResult Index()
{
var model = new HomeIndexViewModel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using OdeToFoodVisualStudio.Models;
using OdeToFoodVisualStudio.Services;

namespace OdeToFoodVisualStudio.Pages.Restaurants
{
[Authorize]
public class EditModel : PageModel
{
private IRestaurantData _restaurantData;
Expand Down
13 changes: 11 additions & 2 deletions OdeToFoodVisualStudio/OdeToFoodVisualStudio/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@ namespace OdeToFoodVisualStudio
{
public class Program
{

public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
public static IWebHost BuildWebHost(string[] args)
{
IConfigurationBuilder config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("github.json", optional: false, reloadOnChange: true)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

return WebHost.CreateDefaultBuilder(args)
.UseConfiguration(config.Build())
.UseStartup<Startup>()
.Build();
}
}
}
56 changes: 55 additions & 1 deletion OdeToFoodVisualStudio/OdeToFoodVisualStudio/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;
Expand All @@ -7,9 +11,13 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using OdeToFoodVisualStudio.Data;
using OdeToFoodVisualStudio.Services;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;

namespace OdeToFoodVisualStudio
{
Expand All @@ -26,6 +34,48 @@ public Startup(IConfiguration configuration)
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "GitHub";
})
.AddCookie()
.AddOAuth("GitHub", options =>
{
options.ClientId = _configuration.GetSection("GitHub").GetValue<string>("ClientId");
options.ClientSecret = _configuration.GetSection("GitHub").GetValue<string>("ClientSecret");
options.CallbackPath = new PathString("/signin-oidc");
options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
options.TokenEndpoint = "https://github.com/login/oauth/access_token";
options.UserInformationEndpoint = "https://api.github.com/user";
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
options.ClaimActions.MapJsonKey("urn:github:login", "login");
options.ClaimActions.MapJsonKey("urn:github:url", "html_url");
options.ClaimActions.MapJsonKey("urn:github:avatar", "avatar_url");
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JObject.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user);
}
};
});

// RDVS: Rider's completion works better with this generic method as it additionally adds the parentheses; additionally, VS overlaps the completion list inside the generic brackets
// with with parameter info
services.AddSingleton<IGreeter, Greeter>(); // singleton scope
Expand All @@ -44,7 +94,11 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, IGreeter

// RDVS: RewriteOptions suggested as FQN in Visual Studio's completion: Scott had to erase the FQN part and import namespace with a quick action
app.UseRewriter(new RewriteOptions().AddRedirectToHttpsPermanent());

app.UseStaticFiles();

app.UseAuthentication();

app.UseMvc(ConfigureRoutes);

app.Run(async (context) =>
Expand Down

0 comments on commit 170462e

Please sign in to comment.