Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CustomSecurityTokenService.cs 4.39 KiB
using System.Collections.Generic;
using System.IdentityModel;
using System.IdentityModel.Configuration;
using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using Coscine.Api.LegacySTS.ModelingObjects;
namespace Coscine.Api.LegacySTS.Security
{
public class CustomSecurityTokenService : SecurityTokenService
{
private static readonly string[] SupportedWebApps = { };
private UserObject _userObject;
public CustomSecurityTokenService(SecurityTokenServiceConfiguration securityTokenServiceConfiguration, UserObject userObject) : base(securityTokenServiceConfiguration)
{
_userObject = userObject;
}
private static void ValidateAppliesTo(EndpointReference appliesTo)
{
if (SupportedWebApps == null || SupportedWebApps.Length == 0) return;
var validAppliesTo = SupportedWebApps.Any(x => appliesTo.Uri.Equals(x));
if (!validAppliesTo)
{
throw new InvalidRequestException(string.Format("The 'appliesTo' address '{0}' is not valid.", appliesTo.Uri.OriginalString));
}
}
protected override Scope GetScope(ClaimsPrincipal principal, RequestSecurityToken request)
{
ValidateAppliesTo(request.AppliesTo);
var scope = new Scope(request.AppliesTo.Uri.OriginalString, SecurityTokenServiceConfiguration.SigningCredentials);
// TODO maybe set?
var encryptionCertificate = "";
if (!string.IsNullOrEmpty(encryptionCertificate))
{
// Important note on setting the encrypting credentials.
// In a production deployment, you would need to select a certificate that is specific to the RP that is requesting the token.
// You can examine the 'request' to obtain information to determine the certificate to use.
var encryptingCertificate = GetCertificate();// encryptionCertificate);
var encryptingCredentials = new X509EncryptingCredentials(encryptingCertificate);
scope.EncryptingCredentials = encryptingCredentials;
}
else
{
// If there is no encryption certificate specified, the STS will not perform encryption.
// This will succeed for tokens that are created without keys (BearerTokens) or asymmetric keys.
scope.TokenEncryptionRequired = false;
}
scope.ReplyToAddress = request.ReplyTo;
if(request.ReplyTo == "")
{
scope.ReplyToAddress = request.Context;
}
if (scope.ReplyToAddress.Contains(","))
{
scope.ReplyToAddress = scope.ReplyToAddress.Substring(0, scope.ReplyToAddress.IndexOf(","));
}
return scope;
}
protected override ClaimsIdentity GetOutputClaimsIdentity(ClaimsPrincipal principal, RequestSecurityToken request, Scope scope)
{
var claims = new List<Claim>()
{
new Claim(System.IdentityModel.Claims.ClaimTypes.Name, _userObject.DisplayName),
new Claim(System.IdentityModel.Claims.ClaimTypes.Surname, _userObject.DisplayName.Contains(" ") ? _userObject.DisplayName.Split(' ')[0] : _userObject.DisplayName),
new Claim(System.IdentityModel.Claims.ClaimTypes.GivenName, _userObject.DisplayName.Contains(" ") ? _userObject.DisplayName.Split(' ')[1] : ""),
new Claim(System.IdentityModel.Claims.ClaimTypes.NameIdentifier, _userObject.Id.ToString()),
};
if (_userObject.EmailAddress != null)
{
claims.Add(new Claim(System.IdentityModel.Claims.ClaimTypes.Email, _userObject.EmailAddress));
}
var identity = new ClaimsIdentity(claims);
return identity;
}
public static X509Certificate2 GetCertificate()
{
var pfx = Program.Configuration.GetAndWait("coscine/global/sts/pfx");
var passwordString = Program.Configuration.GetStringAndWait("coscine/global/sts/pfxpassword");
X509Certificate2 x509Certificate2 = new X509Certificate2(pfx, passwordString);
return x509Certificate2;
}
}
}