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"); }
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); } } }
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"); } } }
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"); } }
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); } }
public static List<Claim> GetOutputClaims(ClaimsPrincipal principal, RequestDetails requestDetails, IClaimsRepository claimsRepository) { return claimsRepository.GetClaims(SanitizeInternalClaims(principal), requestDetails).ToList(); }
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); }
protected virtual void AnalyzeRst(RequestSecurityToken rst, RequestDetails options) { if (rst == null) { throw new ArgumentNullException("request"); } options.Request = rst; }
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; }
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"); } } }
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"); } }
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; }
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); }
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"); } }
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; }
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; }
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"); }
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."); }
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."); } } }
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"); } }
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"); } }