public virtual IEnumerable<Claim> GetClaims(ClaimsPrincipal principal, RequestDetails requestDetails)
        {
            var userName = principal.Identity.Name;
            var claims = new List<Claim>(from c in principal.Claims select c);

            var nameIdClaim = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
            if (nameIdClaim == null)
            {
                claims.Add(new Claim(ClaimTypes.NameIdentifier, userName));
            }

            // email address
            var membership = Membership.FindUsersByName(userName)[userName];
            if (membership != null)
            {
                var email = membership.Email;
                if (!string.IsNullOrEmpty(email))
                {
                    claims.Add(new Claim(ClaimTypes.Email, email));
                }
            }

            // roles
            GetRolesForToken(userName).ToList().ForEach(role => claims.Add(new Claim(ClaimTypes.Role, role)));

            // profile claims
            claims.AddRange(GetProfileClaims(userName));

            return claims;
        }
        public HttpResponseMessage Get()
        {
            Tracing.Start("OIDC UserInfo endpoint");

            var details = new RequestDetails {IsOpenIdRequest = true};
            var scopeClaims = ClaimsPrincipal.Current.FindAll(OAuth2Constants.Scope).ToList();
            var requestedClaims = ClaimsPrincipal.Current.FindAll("requestclaim").ToList();

            if (scopeClaims.Count > 0)
            {
                var scopes = new List<string>(scopeClaims.Select(sc => sc.Value));
                details.OpenIdScopes = scopes;
            }

            if (requestedClaims.Count > 0)
            {
                var requestClaims = new RequestClaimCollection();
                requestedClaims.ForEach(rc => requestClaims.Add(new RequestClaim(rc.Value)));

                details.ClaimsRequested = true;
                details.RequestClaims = requestClaims;
            }

            var principal = Principal.Create("OpenIdConnect",
                new Claim(ClaimTypes.Name, ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value));

            var claims = ClaimsRepository.GetClaims(principal, details);

            var dictionary = new Dictionary<string, string>();
            foreach (var claim in claims)
            {
                if (!dictionary.ContainsKey(claim.Type))
                {
                    dictionary.Add(claim.Type, claim.Value);
                }
                else
                {
                    var currentValue = dictionary[claim.Type];
                    dictionary[claim.Type] = currentValue += ("," + claim.Value);
                }
            }

            return Request.CreateResponse(HttpStatusCode.OK, dictionary, "application/json");
        }
Example #3
0
        protected virtual void ValidateRelyingParty(RequestDetails details)
        {
            if (details.RelyingPartyRegistration != null)
            {
                if (details.RelyingPartyRegistration.Enabled == false)
                {
                    Tracing.Error("Relying party is disabled");

                    throw new InvalidRequestException("Invalid realm: " + details.Realm.Uri.AbsoluteUri);
                }
            }
        }
Example #4
0
 protected virtual void ValidateReplyTo(RequestDetails details)
 {
     // check if replyto is part of a registered realm (when not explicitly registered in config)
     if (!details.IsReplyToFromConfiguration)
     {
         if (_configuration.WSFederation.RequireReplyToWithinRealm && (!details.ReplyToAddressIsWithinRealm))
         {
             Tracing.Error(
                 "Configuration requires that ReplyTo is a sub-address of the realm - this is not the case");
             throw new InvalidRequestException("Invalid ReplyTo");
         }
     }
 }
Example #5
0
 protected virtual void ValidateEncryption(RequestDetails details)
 {
     // check if token must be encrypted
     if (_configuration.Global.RequireEncryption && (!details.UsesEncryption))
     {
         Tracing.Error("Configuration requires encryption - but no key available");
         throw new InvalidRequestException("No encryption key available");
     }
 }
Example #6
0
        protected virtual void ValidateKnownRealm(RequestDetails details)
        {
            // check if realm is allowed
            if (_configuration.Global.RequireRelyingPartyRegistration && (!details.IsKnownRealm))
            {
                Tracing.Error("Configuration requires a known realm - but realm is not registered");

                throw new InvalidRequestException("Invalid realm: " + details.Realm.Uri.AbsoluteUri);
            }
        }
Example #7
0
 public static List<Claim> GetOutputClaims(ClaimsPrincipal principal, RequestDetails requestDetails,
     IClaimsRepository claimsRepository)
 {
     return claimsRepository.GetClaims(SanitizeInternalClaims(principal), requestDetails).ToList();
 }
Example #8
0
        protected virtual void AnalyzeEncryption(RequestDetails details)
        {
            if (details.EncryptingCertificate == null)
            {
                X509Certificate2 requestCertificate;
                if (TryGetEncryptionCertificateFromRequest(details.Realm, out requestCertificate))
                {
                    details.EncryptingCertificate = requestCertificate;
                    Tracing.Information("Encrypting certificate set from RST");
                }
            }

            details.UsesEncryption = (details.EncryptingCertificate != null);
            Tracing.Information("Token encryption: " + details.UsesEncryption);
        }
Example #9
0
        protected virtual void AnalyzeRst(RequestSecurityToken rst, RequestDetails options)
        {
            if (rst == null)
            {
                throw new ArgumentNullException("request");
            }

            options.Request = rst;
        }
Example #10
0
        protected virtual ClaimsIdentity GetActAsClaimsIdentity(ClaimsIdentity clientIdentity,
            RequestDetails requestDetails)
        {
            //var actAsSubject = requestDetails.Request.ActAs..GetSubject()[0];
            var actAsIdentity = requestDetails.Request.ActAs.GetIdentities().First();

            // find the last actor in the actAs identity
            var lastActor = actAsIdentity;
            while (lastActor.Actor != null)
            {
                lastActor = lastActor.Actor;
            }

            // set the caller's identity as the last actor in the delegation chain
            lastActor.Actor = clientIdentity;

            Tracing.Information("ActAs client identity: " + actAsIdentity.Name);
            Tracing.Information("ActAs actor identity : " + actAsIdentity.Actor.Name);

            // return the actAsIdentity instead of the caller's identity in this case
            return actAsIdentity;
        }
Example #11
0
        protected virtual void AnalyzeReplyTo(RequestDetails details)
        {
            var rp = details.RelyingPartyRegistration;

            // determine the reply to address (only relevant for passive requests)
            if (rp != null && rp.ReplyTo != null)
            {
                details.ReplyToAddress = rp.ReplyTo;
                details.IsReplyToFromConfiguration = true;

                // check if reply to is a sub-address of the realm address
                if (details.ReplyToAddress.AbsoluteUri.StartsWith(details.Realm.Uri.AbsoluteUri,
                    StringComparison.OrdinalIgnoreCase))
                {
                    details.ReplyToAddressIsWithinRealm = true;
                }

                Tracing.Information(string.Format("ReplyTo Address set from configuration: {0}",
                    details.ReplyToAddress.AbsoluteUri));
            }
            else
            {
                if (!string.IsNullOrEmpty(details.Request.ReplyTo))
                {
                    if (_configuration.WSFederation.AllowReplyTo)
                    {
                        // explicit address
                        details.ReplyToAddress = new Uri(details.Request.ReplyTo);
                        Tracing.Information(string.Format("Explicit ReplyTo address set: {0}",
                            details.ReplyToAddress.AbsoluteUri));

                        // check if reply to is a sub-address of the realm address
                        if (details.ReplyToAddress.AbsoluteUri.StartsWith(details.Realm.Uri.AbsoluteUri,
                            StringComparison.OrdinalIgnoreCase))
                        {
                            details.ReplyToAddressIsWithinRealm = true;
                        }

                        Tracing.Information(string.Format("ReplyTo Address is within Realm: {0}",
                            details.ReplyToAddressIsWithinRealm));
                    }
                    else
                    {
                        // same as realm
                        details.ReplyToAddress = details.Realm.Uri;
                        details.ReplyToAddressIsWithinRealm = true;
                        Tracing.Warning(
                            string.Format(
                                "ReplyTo address of ({0}) was supplied, but since configuration does not allow ReplyTo, the realm address is used",
                                details.Request.ReplyTo));
                    }
                }
                else
                {
                    // same as realm
                    details.ReplyToAddress = details.Realm.Uri;
                    details.ReplyToAddressIsWithinRealm = true;
                    Tracing.Information("ReplyTo address set to realm address");
                }
            }
        }
Example #12
0
        protected virtual void AnalyzeRequestClaims(RequestDetails details)
        {
            // check if specific claims are requested
            if (details.Request.Claims != null && details.Request.Claims.Count > 0)
            {
                details.ClaimsRequested = true;
                details.RequestClaims = details.Request.Claims;

                var requestClaims = new StringBuilder(20);
                details.RequestClaims.ToList().ForEach(rq => requestClaims.AppendFormat("{0}\n", rq.ClaimType));
                Tracing.Information("Specific claims requested");
                Tracing.Information(string.Format("Request claims: {0}", requestClaims));
            }
            else
            {
                Tracing.Information("No request claims");
            }
        }
Example #13
0
        protected virtual RelyingParty AnalyzeRelyingParty(RequestDetails details)
        {
            // check if the relying party is registered
            RelyingParty rp = null;
            if (RelyingPartyRepository.TryGet(details.Realm.Uri.AbsoluteUri, out rp))
            {
                details.RelyingPartyRegistration = rp;
                details.IsKnownRealm = true;

                var traceString = string.Format("Relying Party found in registry - Realm: {0}", rp.Realm.AbsoluteUri);

                if (!string.IsNullOrEmpty(rp.Name))
                {
                    traceString += string.Format(" ({0})", rp.Name);
                }

                Tracing.Information(traceString);

                if (rp.EncryptingCertificate != null)
                {
                    details.EncryptingCertificate = rp.EncryptingCertificate;
                    Tracing.Information("Encrypting certificate set from registry");
                }
            }
            else
            {
                Tracing.Information("Relying party is not registered.");
            }
            return rp;
        }
Example #14
0
        protected virtual void AnalyzeRealm(RequestSecurityToken rst, RequestDetails options)
        {
            // check realm
            if (rst.AppliesTo == null || rst.AppliesTo.Uri == null)
            {
                throw new ArgumentNullException("AppliesTo");
                //throw new MissingAppliesToException("AppliesTo is missing");
            }

            options.Realm = new EndpointAddress(rst.AppliesTo.Uri);
        }
Example #15
0
 protected virtual void AnalyzeOperationContext(RequestDetails details)
 {
     // determine if this is a WCF call
     if (OperationContext.Current != null)
     {
         details.IsActive = true;
         Tracing.Information("Active request");
     }
     else
     {
         Tracing.Information("Passive request");
     }
 }
Example #16
0
        public RequestDetails Analyze(RequestSecurityToken rst, ClaimsPrincipal principal)
        {
            if (rst == null)
            {
                throw new ArgumentNullException("rst");
            }

            if (principal == null)
            {
                throw new ArgumentNullException("principal");
            }

            Tracing.Information("Starting PolicyOptions creation");

            var clientIdentity = AnalyzeClientIdentity(principal);

            var details = new RequestDetails
            {
                ClientIdentity = clientIdentity,
                IsActive = false,
                Realm = null,
                IsKnownRealm = false,
                UsesSsl = false,
                UsesEncryption = false,
                ReplyToAddress = null,
                ReplyToAddressIsWithinRealm = false,
                IsReplyToFromConfiguration = false,
                EncryptingCertificate = null,
                ClaimsRequested = false,
                RequestClaims = null,
                Request = null,
                IsActAsRequest = false,
                RelyingPartyRegistration = null
            };

            AnalyzeRst(rst, details);
            AnalyzeKeyType(rst);
            AnalyzeRealm(rst, details);
            AnalyzeOperationContext(details);
            AnalyzeDelegation(rst, details);
            AnalyzeRelyingParty(details);
            AnalyzeTokenType(rst, details);
            AnalyzeEncryption(details);
            AnalyzeReplyTo(details);
            AnalyzeSsl(details);
            AnalyzeRequestClaims(details);

            Tracing.Information("PolicyOptions creation done.");

            _details = details;
            return details;
        }
Example #17
0
 protected virtual void AnalyzeSsl(RequestDetails details)
 {
     // determine if reply to is via SSL
     details.UsesSsl = (details.ReplyToAddress.Scheme == Uri.UriSchemeHttps);
     Tracing.Information(string.Format("SSL used:{0}", details.UsesSsl));
 }
 public IEnumerable<Claim> ProcessClaims(ClaimsPrincipal incomingPrincipal, IdentityProvider identityProvider,
     RequestDetails details)
 {
     return incomingPrincipal.Claims;
 }
Example #19
0
        public void Validate(RequestDetails details)
        {
            if (details == null)
            {
                throw new ArgumentNullException("details");
            }

            Tracing.Information("Starting policy validation");

            ValidateKnownRealm(details);
            ValidateRelyingParty(details);
            ValidateReplyTo(details);
            ValidateEncryption(details);
            ValidateDelegation(details);

            Tracing.Information("Policy Validation succeeded");
        }
Example #20
0
        protected virtual ClaimsIdentity GetExternalOutputClaims(ClaimsPrincipal principal,
            RequestDetails requestDetails)
        {
            var idpClaim =
                principal.FindFirst(
                    c => c.Type == Constants.Claims.IdentityProvider && c.Issuer == Constants.InternalIssuer);

            if (idpClaim == null)
            {
                throw new InvalidOperationException("No identity provider claim found.");
            }

            IdentityProvider idp = null;
            if (IdentityProviderRepository.TryGet(idpClaim.Value, out idp))
            {
                var transformedClaims =
                    ClaimsTransformationRulesRepository.ProcessClaims(SanitizeInternalClaims(principal), idp,
                        requestDetails);
                var id = new ClaimsIdentity(transformedClaims, "External");

                id.AddClaim(new Claim(Constants.Claims.IdentityProvider, idp.Name));
                return id;
            }

            throw new InvalidRequestException("Invalid identity provider.");
        }
Example #21
0
        protected virtual void ValidateDelegation(RequestDetails details)
        {
            // check for ActAs request
            if (details.IsActAsRequest)
            {
                if (!_configuration.WSTrust.EnableDelegation)
                {
                    Tracing.Error("Request is ActAs request - but ActAs is not enabled");
                    throw new InvalidRequestException("Request is ActAs request - but ActAs is not enabled");
                }

                if (
                    !DelegationRepository.IsDelegationAllowed(details.ClientIdentity.Name, details.Realm.Uri.AbsoluteUri))
                {
                    Tracing.Error("ActAs mapping not found.");
                    throw new InvalidRequestException("ActAs mapping not found.");
                }
            }
        }
Example #22
0
        protected virtual void AnalyzeTokenType(RequestSecurityToken rst, RequestDetails details)
        {
            if (!string.IsNullOrWhiteSpace(rst.TokenType))
            {
                details.TokenType = rst.TokenType;
                Tracing.Information("Token type set from RST: " + details.TokenType);

                return;
            }

            if (details.IsKnownRealm && details.RelyingPartyRegistration.TokenType != null)
            {
                switch (details.RelyingPartyRegistration.TokenType.Value)
                {
                    case TokenType.SAML11:
                        details.TokenType = TokenTypes.Saml11TokenProfile11;
                        break;
                    case TokenType.SAML20:
                        details.TokenType = TokenTypes.Saml2TokenProfile11;
                        break;
                    case TokenType.JWT:
                        details.TokenType = TokenTypes.JsonWebToken;
                        break;
                    default:
                        var error = "Invalid token type: " + details.RelyingPartyRegistration.TokenType.Value;
                        Tracing.Error(error);
                        throw new InvalidRequestException(error);
                }

                Tracing.Information("Token type set from RP registration: " + details.TokenType);
            }
            else
            {
                details.TokenType = _configuration.Global.DefaultWSTokenType;
                Tracing.Information("Token Type not specified, using default token type");
            }
        }
Example #23
0
 protected virtual void AnalyzeDelegation(RequestSecurityToken rst, RequestDetails details)
 {
     // check for identity delegation request
     if (rst.ActAs != null)
     {
         details.IsActAsRequest = true;
         Tracing.Information("Request is ActAs request");
     }
 }