Skip to content
Snippets Groups Projects
CustomSecurityTokenService.cs 4.39 KiB
Newer Older
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;
        }
    }
}