Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Experimental/newSaml2
  • Fix/xxxx-migrateLogin
  • Hotfix/1234-handlingMergeToken
  • Hotfix/1354-workingFHLogin
  • Hotfix/1357-ymlFile
  • Hotfix/1370-swaggerDescription
  • Hotfix/1545-emptyUserGraphs
  • Hotfix/2087-efNet6
  • Hotfix/2103-RepositoryurlstoConsulUpdateMappingGivennameDev
  • Hotfix/2103-RepositoryurlstoConsulUpdateMappingGivennameUiv2
  • Hotfix/2169-ignoreAuthContext
  • Hotfix/2576-certificatePatch
  • Hotfix/2592-sameProvider
  • Hotfix/2775-dfnCertRollover
  • Hotfix/64-releaseUDE
  • Issue/1833-newLogin
  • Issue/1910-MigrationtoNET6.0
  • Issue/1964-tokenExpiryUIv2
  • Issue/1974-shibbolethLogout
  • Issue/2078-renamingEntitlementAcceptStaff
  • Issue/2078-renamingEntitlementAcceptStaffUiv2
  • Issue/2115-extendParsingPairwiseId
  • Issue/2147-exchangingCoscineCertificate
  • Issue/2147-exchangingCoscineCertificate-step2
  • Issue/2147-exchangingCoscineCertificate-step3
  • Issue/2309-docs
  • Issue/2325-fixApiTokenMerging
  • Issue/3003-stsInstitute
  • Issue/40-rdsQuotaForUKA
  • Product/1149-dfnaai
  • Product/1287-dotnet5Sharepoint
  • Product/1290-dfnaai
  • Product/1414-fhPrivileges
  • Product/1629-onboardingOtherUniversities
  • Product/797-overhaul
  • Product/917-maintenanceFunctionality
  • Sprint/2020-20
  • Sprint/2020-21
  • Sprint/2020-22
  • Sprint/2021-01
  • Sprint/2021-03
  • Sprint/2021-05
  • Sprint/2021-06
  • Sprint/2021-08
  • Sprint/2021-10
  • Sprint/2021-11
  • Sprint/2021-19
  • Sprint/2021-20
  • Sprint/2021-23
  • Sprint/2022-01
  • Topic/1224-overhaul
  • Topic/1276-DFN-AAIFrontend
  • Topic/1278-dfnAAI
  • Topic/1297-maintenanceBanner
  • Topic/1335-dotnet5Apis
  • Topic/1425-fhPrivileges
  • Topic/1711-extendResourceTypeConfiguration
  • dev
  • gitkeep
  • master
  • top
  • uiv2
  • v1.0.0
  • v1.1.0
  • v1.10.0
  • v1.10.1
  • v1.10.2
  • v1.11.0
  • v1.11.1
  • v1.11.2
  • v1.11.3
  • v1.12.0
  • v1.13.0
  • v1.14.0
  • v1.14.1
  • v1.15.0
  • v1.16.0
  • v1.16.1
  • v1.16.2
  • v1.17.0
  • v1.18.0
  • v1.2.0
  • v1.2.1
  • v1.3.0
  • v1.4.0
  • v1.5.0
  • v1.6.0
  • v1.7.0
  • v1.8.0
  • v1.8.1
  • v1.9.0
  • v1.9.1
  • v2.0.0
  • v2.0.1
  • v2.0.2
  • v2.0.3
  • v2.1.0
  • v2.2.0
  • v2.2.1
  • v2.2.2
  • v2.2.3
  • v2.2.4
  • v2.3.0
  • v2.3.1
  • v2.3.2
  • v2.3.3
  • v2.4.0
  • v2.4.1
  • v2.4.2
  • v2.4.3
  • v2.4.4
  • v3.0.0
  • v3.1.0
  • v3.1.1
  • v3.1.2
  • v3.1.3
  • v3.1.4
  • v4.0.0
  • v4.0.1
  • v4.0.2
  • v4.0.3
  • v4.0.4
  • v4.0.5
  • v4.0.6
  • v4.0.7
  • v4.0.8
  • v4.0.9
  • v4.1.0
  • v4.1.1
129 results

Target

Select target project
  • coscine/backend/apis/sts
1 result
Select Git revision
  • Experimental/newSaml2
  • Fix/xxxx-migrateLogin
  • Hotfix/1234-handlingMergeToken
  • Hotfix/1354-workingFHLogin
  • Hotfix/1357-ymlFile
  • Hotfix/1370-swaggerDescription
  • Hotfix/1545-emptyUserGraphs
  • Hotfix/2087-efNet6
  • Hotfix/2103-RepositoryurlstoConsulUpdateMappingGivennameDev
  • Hotfix/2103-RepositoryurlstoConsulUpdateMappingGivennameUiv2
  • Hotfix/2169-ignoreAuthContext
  • Hotfix/2576-certificatePatch
  • Hotfix/2592-sameProvider
  • Hotfix/2775-dfnCertRollover
  • Hotfix/64-releaseUDE
  • Issue/1833-newLogin
  • Issue/1910-MigrationtoNET6.0
  • Issue/1964-tokenExpiryUIv2
  • Issue/1974-shibbolethLogout
  • Issue/2078-renamingEntitlementAcceptStaff
  • Issue/2078-renamingEntitlementAcceptStaffUiv2
  • Issue/2115-extendParsingPairwiseId
  • Issue/2147-exchangingCoscineCertificate
  • Issue/2147-exchangingCoscineCertificate-step2
  • Issue/2147-exchangingCoscineCertificate-step3
  • Issue/2309-docs
  • Issue/2325-fixApiTokenMerging
  • Issue/3003-stsInstitute
  • Issue/40-rdsQuotaForUKA
  • Product/1149-dfnaai
  • Product/1287-dotnet5Sharepoint
  • Product/1290-dfnaai
  • Product/1414-fhPrivileges
  • Product/1629-onboardingOtherUniversities
  • Product/797-overhaul
  • Product/917-maintenanceFunctionality
  • Sprint/2020-20
  • Sprint/2020-21
  • Sprint/2020-22
  • Sprint/2021-01
  • Sprint/2021-03
  • Sprint/2021-05
  • Sprint/2021-06
  • Sprint/2021-08
  • Sprint/2021-10
  • Sprint/2021-11
  • Sprint/2021-19
  • Sprint/2021-20
  • Sprint/2021-23
  • Sprint/2022-01
  • Topic/1224-overhaul
  • Topic/1276-DFN-AAIFrontend
  • Topic/1278-dfnAAI
  • Topic/1297-maintenanceBanner
  • Topic/1335-dotnet5Apis
  • Topic/1425-fhPrivileges
  • Topic/1711-extendResourceTypeConfiguration
  • dev
  • gitkeep
  • master
  • top
  • uiv2
  • v1.0.0
  • v1.1.0
  • v1.10.0
  • v1.10.1
  • v1.10.2
  • v1.11.0
  • v1.11.1
  • v1.11.2
  • v1.11.3
  • v1.12.0
  • v1.13.0
  • v1.14.0
  • v1.14.1
  • v1.15.0
  • v1.16.0
  • v1.16.1
  • v1.16.2
  • v1.17.0
  • v1.18.0
  • v1.2.0
  • v1.2.1
  • v1.3.0
  • v1.4.0
  • v1.5.0
  • v1.6.0
  • v1.7.0
  • v1.8.0
  • v1.8.1
  • v1.9.0
  • v1.9.1
  • v2.0.0
  • v2.0.1
  • v2.0.2
  • v2.0.3
  • v2.1.0
  • v2.2.0
  • v2.2.1
  • v2.2.2
  • v2.2.3
  • v2.2.4
  • v2.3.0
  • v2.3.1
  • v2.3.2
  • v2.3.3
  • v2.4.0
  • v2.4.1
  • v2.4.2
  • v2.4.3
  • v2.4.4
  • v3.0.0
  • v3.1.0
  • v3.1.1
  • v3.1.2
  • v3.1.3
  • v3.1.4
  • v4.0.0
  • v4.0.1
  • v4.0.2
  • v4.0.3
  • v4.0.4
  • v4.0.5
  • v4.0.6
  • v4.0.7
  • v4.0.8
  • v4.0.9
  • v4.1.0
  • v4.1.1
129 results
Show changes
Commits on Source (3)
Showing
with 332 additions and 86 deletions
...@@ -24,6 +24,10 @@ For ORCiD: ...@@ -24,6 +24,10 @@ For ORCiD:
* Set the values for "coscine/global/orcid/url", "coscine/global/orcid/clientid", "coscine/global/orcid/jwksurl" and "coscine/global/orcid/issuer". * Set the values for "coscine/global/orcid/url", "coscine/global/orcid/clientid", "coscine/global/orcid/jwksurl" and "coscine/global/orcid/issuer".
For Shibboleth:
* Set the values for "coscine/global/shibboleth/url", "coscine/global/shibboleth/metadata" and "coscine/global/shibboleth/contact".
### Links ### Links
* [Commit convention](docs/ESLintConvention.md) * [Commit convention](docs/ESLintConvention.md)
......
...@@ -20,6 +20,14 @@ Instructions for making it run: ...@@ -20,6 +20,14 @@ Instructions for making it run:
* Set the value "coscine/global/ad/password" in your Consul storage with your Active Directory password * Set the value "coscine/global/ad/password" in your Consul storage with your Active Directory password
* Have fun! * Have fun!
For ORCiD:
* Set the values for "coscine/global/orcid/url", "coscine/global/orcid/clientid", "coscine/global/orcid/jwksurl" and "coscine/global/orcid/issuer".
For Shibboleth:
* Set the values for "coscine/global/shibboleth/url", "coscine/global/shibboleth/metadata" and "coscine/global/shibboleth/contact".
### Links ### Links
* [Commit convention](docs/ESLintConvention.md) * [Commit convention](docs/ESLintConvention.md)
......
 using Coscine.STS.Models;
using Coscine.STS.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.IdentityModel.Claims;
using System.Web.Security;
using System.IdentityModel;
using System.IdentityModel.Configuration;
using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using System.Threading.Tasks; using System.Threading.Tasks;
using System;
using Coscine.STS.Utils; using Coscine.STS.Utils;
using System.Net; using Coscine.STS.Data;
using Microsoft.AspNetCore.Identity;
namespace Coscine.STS.Controllers namespace Coscine.STS.Controllers
{ {
public class AccountController : Controller public class AccountController : Controller
{ {
private readonly SignInManager<CoscineUser> _signInManager;
public AccountController(SignInManager<CoscineUser> signInManager)
{
_signInManager = signInManager;
}
[Route("[controller]/login")] [Route("[controller]/login")]
public ActionResult Login(string returnUrl) public ActionResult Login(string returnUrl)
{ {
...@@ -35,11 +31,14 @@ namespace Coscine.STS.Controllers ...@@ -35,11 +31,14 @@ namespace Coscine.STS.Controllers
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
var claims = new[] { new System.Security.Claims.Claim(System.IdentityModel.Claims.ClaimTypes.Name, model.UserId.ToString()) }; var coscineUser = new CoscineUser()
{
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); UserName = model.UserId.ToString(),
Email = model.UserId.ToString() + "@coscine.com"
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); var result = await _signInManager.UserManager.CreateAsync(coscineUser);
await _signInManager.SignInAsync(coscineUser, isPersistent: false);
return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request)); return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request));
} }
......
...@@ -4,14 +4,10 @@ using System.IdentityModel.Services; ...@@ -4,14 +4,10 @@ using System.IdentityModel.Services;
using System.IdentityModel.Tokens; using System.IdentityModel.Tokens;
using System.Security.Claims; using System.Security.Claims;
using Coscine.STS.Security; using Coscine.STS.Security;
using System.Configuration;
using System.Security.Principal;
using System.Threading;
using System.Web.Security;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http;
using System.Net; using Coscine.STS.Utils;
namespace Coscine.STS.Controllers namespace Coscine.STS.Controllers
{ {
...@@ -41,13 +37,8 @@ namespace Coscine.STS.Controllers ...@@ -41,13 +37,8 @@ namespace Coscine.STS.Controllers
} }
} }
} }
var query = Request.Query; string loginUrl = UrlGenerator.GetLoginUrl(Request);
var addedEntries = ""; return Redirect(loginUrl);
foreach(var queryEntry in query)
{
addedEntries += "&" + queryEntry.Key + "=" + queryEntry.Value;
}
return Redirect(Program.MainUrl + "/account/login?ReturnUrl=" + WebUtility.UrlEncode(Program.MainUrl) + addedEntries);
} }
private string ProcessSignIn(Uri url, ClaimsPrincipal user) private string ProcessSignIn(Uri url, ClaimsPrincipal user)
......
using Coscine.ApiCommons.Utils; using Coscine.Database.Model;
using Coscine.Database.Model;
using Coscine.STS.Models; using Coscine.STS.Models;
using Coscine.STS.Utils; using Coscine.STS.Utils;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using System.Net;
using Microsoft.IdentityModel.Logging;
using Coscine.ApiCommons.Models; using Coscine.ApiCommons.Models;
using System.Linq; using System.Linq;
using Coscine.STS.Data;
using Microsoft.AspNetCore.Identity;
using System.DirectoryServices; using System.DirectoryServices;
using System.DirectoryServices.AccountManagement; using System.DirectoryServices.AccountManagement;
#region DupFinder Exclusion
namespace Coscine.STS.Controllers namespace Coscine.STS.Controllers
{ {
public class ORCiDController : Controller public class ORCiDController : Controller
{ {
private readonly SignInManager<CoscineUser> _signInManager;
public ORCiDController(SignInManager<CoscineUser> signInManager)
{
_signInManager = signInManager;
}
[Route("[controller]/login")] [Route("[controller]/login")]
public ActionResult Login(string returnUrl) public ActionResult Login(string returnUrl)
{ {
...@@ -59,15 +60,16 @@ namespace Coscine.STS.Controllers ...@@ -59,15 +60,16 @@ namespace Coscine.STS.Controllers
ExternalIdModel externalIdModel = new ExternalIdModel(); ExternalIdModel externalIdModel = new ExternalIdModel();
var mapping = externalIdModel.GetAllWhere((map) => map.ExternalId_Column == ORCiD && map.ExternalAuthenticatorId == orcidAuthItem.Id); var mapping = externalIdModel.GetAllWhere((map) => map.ExternalId_Column == ORCiD && map.ExternalAuthenticatorId == orcidAuthItem.Id);
Guid userId; UserPlainModel userPlainModel = new UserPlainModel(Program.Configuration);
User user;
if (mapping.Count() > 0) if (mapping.Count() > 0)
{ {
userId = mapping.First().UserId; var userId = mapping.First().UserId;
user = userPlainModel.GetById(userId);
} }
else else
{ {
UserPlainModel userPlainModel = new UserPlainModel(Program.Configuration); user = new User
var user = new User
{ {
DisplayName = (givenname + " " + surname).Trim(), DisplayName = (givenname + " " + surname).Trim(),
EmailAddress = ORCiD + "@orcid.org", EmailAddress = ORCiD + "@orcid.org",
...@@ -81,14 +83,16 @@ namespace Coscine.STS.Controllers ...@@ -81,14 +83,16 @@ namespace Coscine.STS.Controllers
ExternalAuthenticatorId = orcidAuthItem.Id, ExternalAuthenticatorId = orcidAuthItem.Id,
UserId = user.Id UserId = user.Id
}); });
userId = user.Id;
} }
var identityClaims = new[] { new System.Security.Claims.Claim(System.IdentityModel.Claims.ClaimTypes.Name, userId.ToString()) }; var coscineUser = new CoscineUser()
{
var identity = new ClaimsIdentity(identityClaims, CookieAuthenticationDefaults.AuthenticationScheme); UserName = user.Id.ToString(),
Email = user.EmailAddress
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); var result = await _signInManager.UserManager.CreateAsync(coscineUser);
await _signInManager.SignInAsync(coscineUser, isPersistent: false);
return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request)); return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request));
} }
...@@ -97,3 +101,4 @@ namespace Coscine.STS.Controllers ...@@ -97,3 +101,4 @@ namespace Coscine.STS.Controllers
} }
} }
} }
#endregion
\ No newline at end of file
using Coscine.STS.Data;
using Coscine.STS.Models;
using Coscine.STS.Utils;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Coscine.ApiCommons.Models;
using Coscine.Database.Model;
namespace Coscine.STS.Controllers
{
[Route("[controller]/[action]")]
public class ShibbolethController : Controller
{
private readonly SignInManager<CoscineUser> _signInManager;
public ShibbolethController(SignInManager<CoscineUser> signInManager)
{
_signInManager = signInManager;
}
[HttpGet]
public async Task<ActionResult> Callback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
throw new ArgumentException($"Error from external provider: {remoteError}");
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return Redirect(UrlGenerator.GetLoginUrl(Request));
}
ExternalAuthenticatorModel externalAuthenticatorModel = new ExternalAuthenticatorModel();
var shibbolethAuthItem = externalAuthenticatorModel.GetWhere((externalAuthenticator) => externalAuthenticator.DisplayName == "Shibboleth");
ExternalIdModel externalIdModel = new ExternalIdModel();
var identifier = info.Principal.FindFirstValue(ShibbolethAttributeMapping.Identifier);
identifier = identifier.Substring(identifier.IndexOf(">") + 1);
identifier = identifier.Substring(0, identifier.IndexOf("<"));
var mapping = externalIdModel.GetAllWhere((map) => map.ExternalId_Column == identifier && map.ExternalAuthenticatorId == shibbolethAuthItem.Id);
User user;
UserPlainModel userPlainModel = new UserPlainModel(Program.Configuration);
if (mapping.Count() > 0)
{
var userId = mapping.First().UserId;
user = userPlainModel.GetById(userId);
}
else
{
user = ShibbolethAttributeMapping.CreateUser(info.Principal);
userPlainModel.Insert(user);
externalIdModel.Insert(new ExternalId
{
ExternalId_Column = identifier,
ExternalAuthenticatorId = shibbolethAuthItem.Id,
UserId = user.Id
});
}
var coscineUser = new CoscineUser()
{
UserName = user.Id.ToString(),
Email = user.EmailAddress
};
var result = await _signInManager.UserManager.CreateAsync(coscineUser);
result = await _signInManager.UserManager.AddLoginAsync(coscineUser, info);
await _signInManager.SignInAsync(coscineUser, isPersistent: false);
return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request));
}
[HttpPost]
public ActionResult Login(string returnUrl)
{
var provider = "Saml2";
var redirectUrl = Program.MainUrl + "/Shibboleth/Callback?returnUrl=" + returnUrl;
redirectUrl = UrlGenerator.ExtendReturnUrl(redirectUrl, Request);
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties);
}
}
}
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace Coscine.STS.Data
{
public class CoscineDbContext : IdentityDbContext<CoscineUser>
{
public CoscineDbContext(DbContextOptions<CoscineDbContext> options)
: base(options)
{
}
}
}
using System;
using Microsoft.AspNetCore.Identity;
namespace Coscine.STS.Data
{
public class CoscineUser : IdentityUser
{
}
}
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
using Coscine.Database.Model; using Coscine.Database.Model;
using LinqToDB; using LinqToDB;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Coscine.STS.Models namespace Coscine.STS.Models
{ {
......
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
using Coscine.Database.Model; using Coscine.Database.Model;
using LinqToDB; using LinqToDB;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Coscine.STS.Models namespace Coscine.STS.Models
{ {
......
...@@ -7,9 +7,13 @@ namespace Coscine.STS ...@@ -7,9 +7,13 @@ namespace Coscine.STS
{ {
public class Program : AbstractProgram<ConsulConfiguration> public class Program : AbstractProgram<ConsulConfiguration>
{ {
public static string MainUrl { get public static string HostUrl = $"https://{Dns.GetHostName()}.{System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName}";
public static string ApiPath = $"/coscine/api/{((System.Reflection.Assembly.GetEntryAssembly() != null) ? System.Reflection.Assembly.GetEntryAssembly().GetName().Name : System.Reflection.Assembly.GetExecutingAssembly().GetName().Name)}";
public static string MainUrl {
get
{ {
return $"https://{Dns.GetHostName()}.{System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName}/coscine/api/{((System.Reflection.Assembly.GetEntryAssembly() != null) ? System.Reflection.Assembly.GetEntryAssembly().GetName().Name : System.Reflection.Assembly.GetExecutingAssembly().GetName().Name)}"; return HostUrl + ApiPath;
} }
} }
......
...@@ -9,8 +9,8 @@ using System.Reflection; ...@@ -9,8 +9,8 @@ using System.Reflection;
[assembly: AssemblyDescription("STS is a part of the CoScInE group.")] [assembly: AssemblyDescription("STS is a part of the CoScInE group.")]
[assembly: AssemblyCompany("IT Center, RWTH Aachen University")] [assembly: AssemblyCompany("IT Center, RWTH Aachen University")]
[assembly: AssemblyProduct("STS")] [assembly: AssemblyProduct("STS")]
[assembly: AssemblyVersion("1.6.0.0")] [assembly: AssemblyVersion("1.7.0.0")]
[assembly: AssemblyFileVersion("1.6.0.0")] [assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: AssemblyInformationalVersion("1.6.0.0")] [assembly: AssemblyInformationalVersion("1.7.0.0")]
[assembly: AssemblyCopyright("2019 IT Center, RWTH Aachen University")] [assembly: AssemblyCopyright("2019 IT Center, RWTH Aachen University")]
...@@ -10,20 +10,26 @@ ...@@ -10,20 +10,26 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Coscine.ApiCommons" Version="1.2.2" /> <PackageReference Include="Coscine.ApiCommons" Version="1.2.2" />
<PackageReference Include="Coscine.Database" Version="1.10.0" /> <PackageReference Include="Coscine.Database" Version="1.11.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.2.0" />
<PackageReference Include="Microsoft.IdentityModel" Version="7.0.0" /> <PackageReference Include="Microsoft.IdentityModel" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Razor" Version="2.2.0" /> <PackageReference Include="Microsoft.NET.Sdk.Razor" Version="2.2.0" />
<PackageReference Include="System.DirectoryServices" Version="4.6.0" /> <PackageReference Include="System.DirectoryServices" Version="4.6.0" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="4.6.0" /> <PackageReference Include="System.DirectoryServices.AccountManagement" Version="4.6.0" />
<PackageReference Include="System.DirectoryServices.Protocols" Version="4.6.0" /> <PackageReference Include="System.DirectoryServices.Protocols" Version="4.6.0" />
<PackageReference Include="Sustainsys.Saml2.AspNetCore2" Version="2.3.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.5.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.5.0" />
</ItemGroup> </ItemGroup>
......
...@@ -6,24 +6,21 @@ using System.IdentityModel; ...@@ -6,24 +6,21 @@ using System.IdentityModel;
using System.IdentityModel.Configuration; using System.IdentityModel.Configuration;
using System.IdentityModel.Protocols.WSTrust; using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens; using System.IdentityModel.Tokens;
using System.IO;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace Coscine.STS.Security namespace Coscine.STS.Security
{ {
public class CustomSecurityTokenService : SecurityTokenService public class CustomSecurityTokenService : SecurityTokenService
{ {
static readonly string[] SupportedWebApps = { }; private static readonly string[] SupportedWebApps = { };
public CustomSecurityTokenService(SecurityTokenServiceConfiguration securityTokenServiceConfiguration) : base(securityTokenServiceConfiguration) public CustomSecurityTokenService(SecurityTokenServiceConfiguration securityTokenServiceConfiguration) : base(securityTokenServiceConfiguration)
{ {
} }
static void ValidateAppliesTo(EndpointReference appliesTo) private static void ValidateAppliesTo(EndpointReference appliesTo)
{ {
if (SupportedWebApps == null || SupportedWebApps.Length == 0) return; if (SupportedWebApps == null || SupportedWebApps.Length == 0) return;
...@@ -31,7 +28,7 @@ namespace Coscine.STS.Security ...@@ -31,7 +28,7 @@ namespace Coscine.STS.Security
if (!validAppliesTo) if (!validAppliesTo)
{ {
throw new InvalidRequestException(String.Format("The 'appliesTo' address '{0}' is not valid.", appliesTo.Uri.OriginalString)); throw new InvalidRequestException(string.Format("The 'appliesTo' address '{0}' is not valid.", appliesTo.Uri.OriginalString));
} }
} }
......
using Coscine.ApiCommons; using Coscine.ApiCommons;
using Coscine.STS.Data;
using Coscine.STS.Security;
using Coscine.STS.Utils;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Sustainsys.Saml2;
using Sustainsys.Saml2.Metadata;
using System;
namespace Coscine.STS namespace Coscine.STS
{ {
...@@ -18,10 +25,59 @@ namespace Coscine.STS ...@@ -18,10 +25,59 @@ namespace Coscine.STS
{ {
base.ConfigureServicesExtension(services); base.ConfigureServicesExtension(services);
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) services.AddDbContext<CoscineDbContext>(
.AddCookie( options =>
//o => o.LoginPath = PathString.FromUriComponent(Program.MainUrl + "/account/login") options.UseInMemoryDatabase("CoscineDbContext")
); );
services.AddIdentity<CoscineUser, IdentityRole>()
.AddEntityFrameworkStores<CoscineDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddSaml2(options =>
{
options.SPOptions.EntityId = new EntityId(Program.MainUrl + "/Saml2");
options.SPOptions.PublicOrigin = new Uri(Program.HostUrl);
options.SPOptions.ModulePath = Program.ApiPath + "/Saml2";
options.SPOptions.Compatibility.UnpackEntitiesDescriptorInIdentityProviderMetadata = true;
options.IdentityProviders.Add(
new IdentityProvider(
new EntityId(Program.Configuration.GetStringAndWait("coscine/global/shibboleth/url")), options.SPOptions)
{
MetadataLocation = Program.Configuration.GetStringAndWait("coscine/global/shibboleth/metadata"),
LoadMetadata = true,
});
var contact = new ContactPerson
{
Type = ContactType.Support,
};
contact.EmailAddresses.Add(Program.Configuration.GetStringAndWait("coscine/global/shibboleth/contact"));
options.SPOptions.Contacts.Add(contact);
var attributeConsumingService = new AttributeConsumingService
{
IsDefault = true,
ServiceNames = { new LocalizedName("Saml2", "en") }
};
foreach(var pair in ShibbolethAttributeMapping.LabelMapping)
{
attributeConsumingService.RequestedAttributes.Add(
new RequestedAttribute(pair.Key)
{
FriendlyName = pair.Value,
IsRequired = true,
NameFormat = RequestedAttribute.AttributeNameFormatUri
});
}
options.SPOptions.AttributeConsumingServices.Add(attributeConsumingService);
options.SPOptions.ServiceCertificates.Add(CustomSecurityTokenService.GetCertificate());
});
} }
public override void ConfigureExtension(IApplicationBuilder app, IHostingEnvironment env) public override void ConfigureExtension(IApplicationBuilder app, IHostingEnvironment env)
......
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net; using System.Net;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks;
namespace Coscine.STS.Utils namespace Coscine.STS.Utils
{ {
......
using Coscine.Database.Model;
using System.Collections.Generic;
using System.Security.Claims;
namespace Coscine.STS.Utils
{
public class ShibbolethAttributeMapping
{
public static string Identifier { get; private set; } = "urn:oid:1.3.6.1.4.1.5923.1.1.1.10";
public static Dictionary<string, string> LabelMapping { get; private set; } = new Dictionary<string, string>()
{
{ "urn:oid:2.16.840.1.113730.3.1.241", "DisplayName" },
{ "urn:oid:2.5.4.4", "Surname" },
{ "urn:oid:2.5.4.42", "Givenname" },
{ "urn:oid:0.9.2342.19200300.100.1.3", "EmailAddress" },
{ "urn:oid:1.3.6.1.4.1.5923.1.1.1.9", "Entitlement" },
{ "urn:oid:2.5.4.10", "Organization" },
};
public static void SetUserAttribute(User user, string identifier, object value)
{
switch (identifier)
{
case "urn:oid:2.16.840.1.113730.3.1.241":
user.DisplayName = (string) value;
break;
case "urn:oid:2.5.4.4":
user.Surname = (string)value;
break;
case "urn:oid:2.5.4.42":
user.Givenname = (string)value;
break;
case "urn:oid:0.9.2342.19200300.100.1.3":
user.EmailAddress = (string)value;
break;
case "urn:oid:1.3.6.1.4.1.5923.1.1.1.9":
if (user.Entitlement == null || !user.Entitlement.Contains("employee"))
{
user.Entitlement = (string)value;
}
break;
case "urn:oid:2.5.4.10":
user.Organization = (string)value;
break;
default:
break;
}
}
public static User CreateUser(ClaimsPrincipal principal)
{
User user = new User();
foreach(var key in LabelMapping.Keys)
{
SetUserAttribute(user, key, principal.FindFirstValue(key));
}
return user;
}
}
}
using System; using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IdentityModel;
using System.IdentityModel.Configuration;
using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;
using Microsoft.AspNetCore.Http;
using System.Net; using System.Net;
namespace Coscine.STS.Utils namespace Coscine.STS.Utils
{ {
public class UrlGenerator public class UrlGenerator
{ {
public static string GetLoginUrl(HttpRequest request)
{
var query = request.Query;
var addedEntries = "";
foreach (var queryEntry in query)
{
addedEntries += "&" + queryEntry.Key + "=" + queryEntry.Value;
}
var loginUrl = Program.MainUrl + "/account/login?ReturnUrl=" + WebUtility.UrlEncode(Program.MainUrl) + addedEntries;
return loginUrl;
}
public static string ExtendReturnUrl(string returnUrl, HttpRequest request) public static string ExtendReturnUrl(string returnUrl, HttpRequest request)
{ {
string retString = returnUrl; string retString = returnUrl;
......
...@@ -21,11 +21,19 @@ ...@@ -21,11 +21,19 @@
<br> <br>
<form action="/coscine/api/Coscine.STS/Account/login?returnUrl=@ViewBag.ReturnUrl" method="post"> <form action="/coscine/api/Coscine.STS/Account/login?returnUrl=@ViewBag.ReturnUrl" method="post">
<input data-val="true" data-val-required="$t('login_form_id_required')" id="userId" placeholder="User ID" name="UserId" type="text" value="" class="form-control" /> <input data-val="true" id="userId" placeholder="User ID" name="UserId" type="text" value="" class="form-control" />
<input type="submit" id="guidbutton" value="Sign in using User Id"></input> <input type="submit" id="guidbutton" value="Sign in using User Id"></input>
<input type="hidden" name="wa" value="wsignin1.0" /> <input type="hidden" name="wa" value="wsignin1.0" />
</form> </form>
<br>
<br>
<form action="/coscine/api/Coscine.STS/Shibboleth/login?returnUrl=@ViewBag.ReturnUrl" method="post">
<input type="submit" id="guidbutton" value="Sign in using Shibboleth"></input>
<input type="hidden" name="wa" value="wsignin1.0" />
</form>
<script type="text/javascript"> <script type="text/javascript">
function getORCiDUrl() { function getORCiDUrl() {
var hookupElement = document.getElementById('loginpage'); var hookupElement = document.getElementById('loginpage');
......