/// <summary> /// Validate credentials by generic provider /// </summary> /// <param name="cc">Notice that on STs the controller context is irrelevant</param> /// <param name="inputs"></param> /// <param name="logWriter"></param> /// <returns></returns> public CredentialsValidationResult Validate(ControllerContext cc, IDictionary <string, string> inputs, IIdentifyLogWriter logWriter) { var validationResult = ValidateInput(inputs); if (validationResult.ResultCode != CredentialsValidationResultCode.Success) { logWriter.WriteError("Validate the input failed. Error code: " + validationResult.ResultCode + ". ExternalErrorMessages: " + string.Join("\n-", validationResult.ExternalErrorMessages)); validationResult.ShowErrorViewWhenResultCodeIsNotSuccess = false; return(validationResult); } var username = inputs[UserName]; var password = inputs[Password]; var serviceIdentifier = inputs[ServiceIdentifier]; if (!VerifyIfUserNameIsCorrect(username, logWriter)) { return(new CredentialsValidationResult { ResultCode = CredentialsValidationResultCode.UnknownUserName }); } if (!VerifyPasswordIsCorrect(password, logWriter)) { return(new CredentialsValidationResult { ResultCode = CredentialsValidationResultCode.IncorrectPassword }); } var logResult = new StringBuilder(); logResult.AppendLine( $"Successfully validate generic credentials for username = '******' with service identifier ='{serviceIdentifier}'"); logResult.AppendLine(""); // For this example, we are returning only claims whose types start with "additionalClaims". In reality, here is where you put on your business logic code to return claims. var identity = new ClaimsIdentity(AuthenticationTypes.Password); foreach (var input in inputs) { if (input.Key.StartsWith(AdditionalClaims, StringComparison.InvariantCultureIgnoreCase)) { identity.AddClaim(new Claim(input.Key, input.Value)); logResult.AppendLine($"Additional claims received: type = '{input.Key}' - value ='{input.Value}'"); if (input.Value.Equals("exception")) { throw new GenericProviderSampleException("Generic provider exception is thrown on UsernamePasswordGenericCredentialsValidator as requested"); } } } logWriter.WriteInformation(logResult); return(new CredentialsValidationResult { ResultCode = CredentialsValidationResultCode.Success, ClaimsPrincipal = new ClaimsPrincipal(identity) }); }
/// <summary> /// It is an example how to access protocol connection id and entityId in external modules /// </summary> /// <param name="cc"></param> /// <param name="logWriter"></param> private void LookupProtocolConnection(ControllerContext cc, IIdentifyLogWriter logWriter) { const string temporaryContextKey = "ici_TemporaryProtocolContext"; var httpContext = cc.HttpContext; dynamic temporaryContext = httpContext.Items[temporaryContextKey]; dynamic contextIdKey = temporaryContext.ContextIdKey; string contextId = contextIdKey.ContextId; Guid protocolConnectionId = contextIdKey.ProtocolConnectionId; string protocolConnectionEntityId = contextIdKey.ProtocolConnectionEntityId; logWriter.WriteInformation( $"DummyGenericValidatorUsernamePassword. ContextId = '{contextId}'. Protocol connection id = '{protocolConnectionId}', entityId = '{protocolConnectionEntityId}'"); }
public ClaimsPrincipal Transform(ClaimsPrincipal principal, IDictionary <string, string> inputs, IExternalClaimTransformationPipelineContext pipelineContext) { if (principal == null) { throw new ArgumentNullException(nameof(principal)); } if (principal.Claims.Any(claim => claim.Value.Equals("ctexception"))) { throw new GenericProviderSampleException("Generic provider exception is thrown on GenericProviderSampleClaimTransformation as requested"); } principal.Identities.First() .AddClaim(new Claim("a_sample_static_claim_type", "a_sample_static_claim_value")); _identifyLogWriter.WriteInformation( $"A Static claim('{"a_sample_static_claim_type"}'.'{"a_sample_static_claim_value"}') is added"); return(principal); }
public ClaimsPrincipal Transform(ClaimsPrincipal principal, IDictionary <string, string> inputs, IExternalClaimTransformationPipelineContext pipelineContext) { if (principal == null) { throw new ArgumentNullException("principal"); } // At the time this sample code is written, Identify supports only one identity var type = GetType(); foreach (var identity in principal.Identities) { identity.AddClaim(new Claim(type.FullName, type.AssemblyQualifiedName)); identifyLogWriter.WriteInformation(string.Format(CultureInfo.InvariantCulture, "A new claim is added: [{0},{1}]", type.FullName, type.AssemblyQualifiedName)); } return(principal); }
public ClaimsPrincipal Transform(ClaimsPrincipal principal, IDictionary <string, string> inputs, IExternalClaimTransformationPipelineContext pipelineContext) { if (principal == null) { throw new ArgumentNullException("principal"); } try { var type = GetType(); // each identity provider may add its own identity to the claims principal object // at the time the principal object is passed to this transformation rule, how many identities it contains depends on // what previous transformations it has gone through. // Normally speaking: // 1. After Identify receives a token from an upstream Idp or from the UserNamePassword login, it creates the principal with one identity. // 2. After that, Identify loads claims from the local store into another identity and adds it to the principal (2 identities so far) // 3. There is a setting called "Execute before loading claims from local store" in the claims transformation configuration page which controls // if a transformation should be executed before or after the second identity is added. // 4. Note 1: Other transformations may add more identities to the claims principal. // 5. Note 2: One can choose to add claims to one identity or to all identities depending on specific need. foreach (var identity in principal.Identities) { identity.AddClaim(new Claim(type.FullName, type.AssemblyQualifiedName)); identifyLogWriter.WriteInformation(string.Format(CultureInfo.InvariantCulture, "A new claim is added: [{0},{1}]", type.FullName, type.AssemblyQualifiedName)); } AddConnectionEntityIdentifiers(principal); } catch (InvalidOperationException ex) // this exception type is caught for illustration purpose only { // Ids from 4830 to 4899 are reserved for external components. Pick one that doesn't conflict with other external events in the same set up identifyLogWriter.WriteError(4830, ex); } return(principal); }
public CredentialsValidationResult Validate(ControllerContext cc, IDictionary <string, string> input, IIdentifyLogWriter logWriter) { var validationResult = ValidateInput(input); LookupProtocolConnection(cc, logWriter); if (validationResult.ResultCode != CredentialsValidationResultCode.Success) { logWriter.WriteWarning("Validate the input failed. Error code: " + validationResult.ResultCode + ". ExternalErrorMessages: " + string.Join("\n-", validationResult.ExternalErrorMessages)); validationResult.ShowErrorViewWhenResultCodeIsNotSuccess = true; return(validationResult); } var connectionString = input[ConnectionString]; try { var userRepository = new DummyUserRepository(connectionString); var username = input[UserName].Trim(); var user = userRepository.GetUserByName(username); if (user == null) { logWriter.WriteInformation("User not found. Search username: "******"User information: [UserName: {0}], [Password: {1}], [IsDisabled: {2}], [IsLocked: {3}]", user.Username, user.Password, user.IsDisabled, user.IsLocked)); var password = input[Password].Trim(); if (user.Password.Trim() != password) { validationResult.ExternalErrorMessages.Add("Password is invalid. Expected: " + user.Password); validationResult.ResultCode = CredentialsValidationResultCode.IncorrectPassword; } else if (user.IsDisabled) { validationResult.ResultCode = CredentialsValidationResultCode.UserDisabled; } else if (user.IsLocked) { validationResult.ResultCode = CredentialsValidationResultCode.UserLocked; } else { validationResult.UserIdentity = user.Username; validationResult.ResultCode = CredentialsValidationResultCode.Success; } } } catch (Exception ex) { logWriter.WriteError("An unexpected exception happends. Error message: " + ex.Message + ". StackTrace: " + ex.StackTrace); validationResult.ResultCode = CredentialsValidationResultCode.UnknownError; validationResult.ExternalErrorMessages.Add(ex.Message); } logWriter.WriteInformation("Validation with result code: " + validationResult.ResultCode + ". ExternalErrorMessages: " + string.Join("\n-", validationResult.ExternalErrorMessages)); validationResult.ShowErrorViewWhenResultCodeIsNotSuccess = true; return(validationResult); }