Skip to content

Commit e42c245

Browse files
Add an OpenIddict sample and update the readme file.
1 parent 9accb13 commit e42c245

File tree

72 files changed

+41336
-1
lines changed

Some content is hidden

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

72 files changed

+41336
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@{
2+
Layout = "/Views/Shared/_Layout.cshtml";
3+
}

OpenIddict/OpenIddictIdP/Controllers/AuthorizationController.cs

Lines changed: 438 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
3+
* See https://github.com/openiddict/openiddict-core for more information concerning
4+
* the license and the contributors participating to this project.
5+
*/
6+
7+
using Microsoft.AspNetCore;
8+
using Microsoft.AspNetCore.Mvc;
9+
using openiddictidp.ViewModels.Shared;
10+
11+
namespace openiddictidp.Controllers;
12+
13+
public class ErrorController : Controller
14+
{
15+
[Route("error")]
16+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
17+
public IActionResult Error()
18+
{
19+
// If the error was not caused by an invalid
20+
// OIDC request, display a generic error page.
21+
var response = HttpContext.GetOpenIddictServerResponse();
22+
if (response == null)
23+
{
24+
return View(new ErrorViewModel());
25+
}
26+
27+
return View(new ErrorViewModel
28+
{
29+
Error = response.Error,
30+
ErrorDescription = response.ErrorDescription
31+
});
32+
}
33+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace openiddictidp.Controllers;
5+
6+
public class HomeController : Controller
7+
{
8+
private readonly ILogger<HomeController> _logger;
9+
10+
public HomeController(ILogger<HomeController> logger)
11+
{
12+
_logger = logger;
13+
}
14+
15+
public IActionResult Index()
16+
{
17+
return View();
18+
}
19+
20+
public IActionResult Privacy()
21+
{
22+
return View();
23+
}
24+
25+
public IActionResult Error()
26+
{
27+
return View();
28+
}
29+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Microsoft.AspNetCore.Authentication;
2+
using Microsoft.AspNetCore.Authorization;
3+
using Microsoft.AspNetCore.Identity;
4+
using Microsoft.AspNetCore.Mvc;
5+
using OpenIddict.Abstractions;
6+
using OpenIddict.Validation.AspNetCore;
7+
using openiddictidp.Data;
8+
using System.Collections.Generic;
9+
using System.Threading.Tasks;
10+
using static OpenIddict.Abstractions.OpenIddictConstants;
11+
12+
namespace openiddictidp.Controllers;
13+
14+
[Route("api")]
15+
public class ResourceController : Controller
16+
{
17+
private readonly UserManager<ApplicationUser> _userManager;
18+
19+
public ResourceController(UserManager<ApplicationUser> userManager)
20+
{
21+
_userManager = userManager;
22+
}
23+
24+
[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
25+
[HttpGet("message")]
26+
public async Task<IActionResult> GetMessage()
27+
{
28+
var user = await _userManager.FindByIdAsync(User.GetClaim(Claims.Subject));
29+
if (user is null)
30+
{
31+
return Challenge(
32+
authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme,
33+
properties: new AuthenticationProperties(new Dictionary<string, string>
34+
{
35+
[OpenIddictValidationAspNetCoreConstants.Properties.Error] = Errors.InvalidToken,
36+
[OpenIddictValidationAspNetCoreConstants.Properties.ErrorDescription] =
37+
"The specified access token is bound to an account that no longer exists."
38+
}));
39+
}
40+
41+
return Content($"{user.UserName} has been successfully authenticated.");
42+
}
43+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Rsk.Saml.Services;
4+
using openiddictidp.ViewModels.Saml;
5+
using System;
6+
using System.Threading.Tasks;
7+
8+
namespace openiddictidp.Controllers;
9+
10+
[Authorize]
11+
public class SamlController : Controller
12+
{
13+
private readonly ISamlInteractionService samlInteractionService;
14+
15+
public SamlController(ISamlInteractionService samlInteractionService)
16+
{
17+
this.samlInteractionService = samlInteractionService ?? throw new ArgumentNullException(nameof(samlInteractionService));
18+
}
19+
20+
[HttpGet]
21+
public async Task<IActionResult> IdpInitiatedSso()
22+
{
23+
var serviceProviders = await samlInteractionService.GetIdpInitiatedSsoCompatibleServiceProviders();
24+
var vm = new IdpInitiatedSsoViewModel(serviceProviders);
25+
26+
return View("IdpInitiatedSso", vm);
27+
}
28+
29+
[HttpPost]
30+
public async Task ExecuteSpSso(string serviceProviderId)
31+
{
32+
var ssoResponse = await samlInteractionService.CreateIdpInitiatedSsoResponse(serviceProviderId);
33+
34+
await samlInteractionService.ExecuteIdpInitiatedSso(HttpContext, ssoResponse);
35+
}
36+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using Microsoft.AspNetCore.Authentication;
2+
using Microsoft.AspNetCore.Authorization;
3+
using Microsoft.AspNetCore.Identity;
4+
using Microsoft.AspNetCore.Mvc;
5+
using OpenIddict.Abstractions;
6+
using OpenIddict.Server.AspNetCore;
7+
using openiddictidp.Data;
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Threading.Tasks;
11+
using static OpenIddict.Abstractions.OpenIddictConstants;
12+
13+
namespace openiddictidp.Controllers;
14+
15+
public class UserinfoController : Controller
16+
{
17+
private readonly UserManager<ApplicationUser> _userManager;
18+
19+
public UserinfoController(UserManager<ApplicationUser> userManager)
20+
{
21+
_userManager = userManager;
22+
}
23+
24+
25+
// GET: /api/userinfo
26+
[Authorize(AuthenticationSchemes = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)]
27+
[HttpGet("~/connect/userinfo"), HttpPost("~/connect/userinfo"), Produces("application/json")]
28+
public async Task<IActionResult> Userinfo()
29+
{
30+
var user = await _userManager.FindByIdAsync(User.GetClaim(Claims.Subject));
31+
if (user is null)
32+
{
33+
return Challenge(
34+
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
35+
properties: new AuthenticationProperties(new Dictionary<string, string>
36+
{
37+
[OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidToken,
38+
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] =
39+
"The specified access token is bound to an account that no longer exists."
40+
}));
41+
}
42+
43+
var claims = new Dictionary<string, object>(StringComparer.Ordinal)
44+
{
45+
// Note: the "sub" claim is a mandatory claim and must be included in the JSON response.
46+
[Claims.Subject] = await _userManager.GetUserIdAsync(user)
47+
};
48+
49+
if (User.HasScope(Scopes.Email))
50+
{
51+
claims[Claims.Email] = await _userManager.GetEmailAsync(user);
52+
claims[Claims.EmailVerified] = await _userManager.IsEmailConfirmedAsync(user);
53+
}
54+
55+
if (User.HasScope(Scopes.Phone))
56+
{
57+
claims[Claims.PhoneNumber] = await _userManager.GetPhoneNumberAsync(user);
58+
claims[Claims.PhoneNumberVerified] = await _userManager.IsPhoneNumberConfirmedAsync(user);
59+
}
60+
61+
if (User.HasScope(Scopes.Roles))
62+
{
63+
claims[Claims.Role] = await _userManager.GetRolesAsync(user);
64+
}
65+
66+
// Note: the complete list of standard claims supported by the OpenID Connect specification
67+
// can be found here: http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
68+
69+
return Ok(claims);
70+
}
71+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore;
3+
4+
namespace openiddictidp.Data;
5+
6+
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
7+
{
8+
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
9+
: base(options) { }
10+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using Microsoft.AspNetCore.Identity;
2+
3+
namespace openiddictidp.Data;
4+
5+
// Add profile data for application users by adding properties to the ApplicationUser class
6+
public class ApplicationUser : IdentityUser { }
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
5+
namespace openiddictidp.Helpers;
6+
7+
public static class AsyncEnumerableExtensions
8+
{
9+
public static Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> source)
10+
{
11+
if (source == null)
12+
{
13+
throw new ArgumentNullException(nameof(source));
14+
}
15+
16+
return ExecuteAsync();
17+
18+
async Task<List<T>> ExecuteAsync()
19+
{
20+
var list = new List<T>();
21+
22+
await foreach (var element in source)
23+
{
24+
list.Add(element);
25+
}
26+
27+
return list;
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)