Connecting to Open LDAP fails to bind with System.DirectoryServices.Protocols - binding

I have been trying to connect to Open LDAP using sample code from MSDN (Alex Tcherniakhovski)
http://blogs.msdn.com/b/alextch/archive/2012/05/07/sample-code-to-query-openldap-directory-via-net-system-directoryservices-protocols.aspx
I have tried on PORT 636 : ssl as it is in the sample code
And on PORT 389 non ssl to see if i could succeed
When trying on PORT 389 (with the same credentials I could connect to the OPEN LDAP using Softerra LDAP Browser)
I get the following error : The distinguished name contains invalid syntax.
I ran Microsoft Network Monitor and found out that some unwanted characters ââ get added to my Bind request just before my name. These characters never appear in the dotnet solution yet they are part of the request and make it fail.
Do you have an idea of how to get rid of these ?
I would have shown an image but i am not allowed.
My monitor shows BindRequest: Version:3, Name:ââcn=Manager,dc=...
in the dotnet code name is "cn=Manager,dc=.."
Using the code as is with SSL on port 636 lead to the following error : The LDAP server is unavailable.
I get the same error trying to connect with sslbind from Solution DirectoryServices.Protocol downloaded from here.
http://www.microsoft.com/en-us/download/confirmation.aspx?id=18086
Thanks for your help
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.Globalization;
using System.Net;
using System.Security;
namespace OpenLDAPNextUID
{
public class LDAPHelper
{
private readonly LdapConnection ldapConnection;
private readonly string searchBaseDN;
private readonly int pageSize;
public LDAPHelper(
string searchBaseDN,
string hostName,
int portNumber,
AuthType authType,
string connectionAccountName,
SecureString connectionAccountPassword,
int pageSize)
{
var ldapDirectoryIdentifier = new LdapDirectoryIdentifier(
hostName,
portNumber,
true,
false);
var networkCredential = new NetworkCredential(
connectionAccountName,
connectionAccountPassword);
ldapConnection = new LdapConnection(
ldapDirectoryIdentifier,
networkCredential)
{AuthType = authType};
ldapConnection.SessionOptions.ProtocolVersion = 3;
this.searchBaseDN = searchBaseDN;
this.pageSize = pageSize;
}
public IEnumerable<SearchResultEntryCollection> PagedSearch(
string searchFilter,
string[] attributesToLoad)
{
var pagedResults = new List<SearchResultEntryCollection>();
var searchRequest = new SearchRequest
(searchBaseDN,
searchFilter,
SearchScope.Subtree,
attributesToLoad);
var searchOptions = new SearchOptionsControl(SearchOption.DomainScope);
searchRequest.Controls.Add(searchOptions);
var pageResultRequestControl = new PageResultRequestControl(pageSize);
searchRequest.Controls.Add(pageResultRequestControl);
while (true)
{
var searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest);
var pageResponse = (PageResultResponseControl)searchResponse.Controls[0];
yield return searchResponse.Entries;
if (pageResponse.Cookie.Length == 0)
break;
pageResultRequestControl.Cookie = pageResponse.Cookie;
}
}
}
}
namespace OpenLDAP
{
class Program
{
static void Main(string[] args)
{
var password = new[]{'P','a','s','s','w','#','r','d'};
var secureString = new SecureString();
foreach (var character in password)
secureString.AppendChar(character);
var baseOfSearch = "dc=fabrikam,dc=com";
var ldapHost = "ubuntu.fabrikam.com";
var ldapPort = 636; //SSL
var ldapPort = 389; //not SSL
var connectAsDN = "cn=admin,dc=fabrikam,dc=com";
var pageSize = 1000;
var openLDAPHelper = new LDAPHelper(
baseOfSearch,
ldapHost,
ldapPort,
AuthType.Basic,
connectAsDN,
secureString,
pageSize);
var searchFilter = "nextUID=*";
var attributesToLoad = new[] {"nextUID"};
var pagedSearchResults = openLDAPHelper.PagedSearch(
searchFilter,
attributesToLoad);
foreach (var searchResultEntryCollection in pagedSearchResults)
foreach (SearchResultEntry searchResultEntry in searchResultEntryCollection)
Console.WriteLine(searchResultEntry.Attributes["nextUID"][0]);
Console.Read();
}
}
}

Related

Fill Dataset From sqlite

How can this function be modified.
I want to use it to fill in the dataset from sqllite.
error
public void fillDATASET( DataSet ds, string tablename, string query)
{
string dbPath = Path.Combine(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal),
"Department.db3");
var conn = new SQLite.SQLiteConnection(dbPath);
using (Mono.Data.Sqlite.SqliteCommand cmd = new SqliteCommand(query, conn))// error conn
{
using (var DataAdapterd = new SqliteDataAdapter(cmd))
{
ds.Clear();
DataAdapterd.Fill(ds, tablename);
}
}
}
This is because you use two different libraries.
var conn = new SQLite.SQLiteConnection(dbPath);
here you used the method in sqlite-net-pcl nuget,
Mono.Data.Sqlite.SqliteCommand cmd = new SqliteCommand(query, conn)
here you want use the method in System.Data.SQLite.Core nuget.
So you need to use a unified.
For example(use System.Data.SQLite.Core nuget):
using System.Data;
using System.Data.SQLite;
public void fillDATASET(DataSet ds, string tablename, string query)
{
string dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal),
"Department.db3");
var conn = new SQLiteConnection(dbPath);
using (SQLiteCommand cmd = new SQLiteCommand(query, conn))// error conn
{
using (var DataAdapterd = new SQLiteDataAdapter(cmd))
{
ds.Clear();
DataAdapterd.Fill(ds, tablename);
}
}
}

Dynamic Url rewrite in ASP.NET CORE

I'm trying to rewrite a URL, and detect if a portion of the URL exists,
then process that string to finally create a final URL.
From this article, I found so far a way to replace segments of the URL using a regex.
My case is the following:
given the URL
www.whatever.com/segment1/segment2?parameter=value
I need to detect if the text "parameter=" exist in the URL and then process the value and get something like:
www.whatever.com/segment1/segment2?parameter=valueConverted
First, I tried doing something like:
var options = new RewriteOptions()
.AddRedirect("segment1/segment2/(.*)", "segment2/$1");
which worked fine but I was later asked to process the value of the parameter.
But I have not found something similar to this yet:
var options = new RewriteOptions()
.AddRewrite(#"^param=$", "param=" MethodCall(how to send value here?) );
Any guidance?
I found some interesting articles like this that helped me accomplish this... take a look at my final code:
public void Configure(IApplicationBuilder app ...
{
var options = new RewriteOptions()
.Add(new MyCustomRules());
}
...
public class MyCustomRules : Microsoft.AspNetCore.Rewrite.IRule
{
private int StatusCode { get; } = (int)System.Net.HttpStatusCode.MovedPermanently;
private const string PARAMETER = "parameter=";
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var host = request.Host;
var url = request.Path.Value;
var queryString = request.QueryString.Value;
if (queryString.Contains(PARAMETER, StringComparison.OrdinalIgnoreCase))
{
var host = request.Host;
var originalText = queryString.Split(PARAMETER)[1];
var convertedText = processText.Method(originalText);
var newUrl = request.Scheme + host.Value + request.Path + "?" + PARAMETER + convertedText;
var response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location] = newUrl;
context.Result = RuleResult.EndResponse;
return;
}
context.Result = RuleResult.ContinueRules;
return;
}
}
UPDATE: you have to be careful about redirect Looping.

StackExchange.Redis can't write to or read from local Redis Server when I deploy my asp.Net Mvc application to IIS 8.5 on Windows Server 2012 R2

I have an asp.net mvc application which works on .Net 4.6.2 framework. This app has Dependency Injection with Inversion of Control technics using SimpleInjector and Aspect Oriented Programming technics using PostSharp.
StackExchange.Redis library working fine on my local machine when I start to debug my solution in Visual Studio 2015 Ent. on Windows 10 Pro. I can write to and read from redis server on my local also my app can write to and read from redis server on my local when I deploy/publish my app IIS server on my remote server.
But I can't write the redis server on remote server. I check the ports and firewalls but it can't write or read in any way. Also when I trace my app it can successfully connect to redis server on same server also can send commands to it but when look up to redis monitor it does not show that commands.
What could be cause to this?
Code Samples are below
Redis Cache Manager
using System;
using System.Collections.Generic;
using System.Configuration;
using Newtonsoft.Json;
using StackExchange.Redis;
namespace Cits.Portal.Core.CrossCuttingConcern.Caching.Redis
{
public class RedisCacheManager : ICacheManager
{
private static readonly Lazy<ConnectionMultiplexer> LazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
var configurationOptions = new ConfigurationOptions();
#if DEBUG
configurationOptions.EndPoints.Add("localhost", 6379);
#else
configurationOptions.EndPoints.Add("141.11.11.212", 6379);
#endif
configurationOptions.AllowAdmin = true;
configurationOptions.AbortOnConnectFail = false;
return ConnectionMultiplexer.Connect(configurationOptions);
});
public static ConnectionMultiplexer Connection => LazyConnection.Value;
public static IDatabase RedisCache => Connection.GetDatabase();
public void Add(string key, object data, int cacheTime)
{
if (data == null || IsAdd(key))
return;
var value = TimeSpan.FromMinutes(cacheTime);
RedisCache.StringSet(key, Serialize(data), value);
}
public T Get<T>(string key)
{
var value = RedisCache.StringGet(key);
if (!value.HasValue)
return default(T);
return Deserialize<T>(value);
}
public bool IsAdd(string key)
{
return RedisCache.KeyExists(key);
}
public void Remove(string key)
{
RedisCache.KeyDelete(key);
}
public void RemoveByPattern(string pattern)
{
var endPoints = Connection.GetEndPoints();
foreach (var endpoint in endPoints)
{
var server = Connection.GetServer(endpoint);
var enumerable = server.Keys(RedisCache.Database, pattern);
foreach (var current in enumerable)
Remove(current);
}
}
public void Clear()
{
var endPoints = Connection.GetEndPoints();
foreach (var endpoint in endPoints)
{
var server = Connection.GetServer(endpoint);
var enumerable = server.Keys(RedisCache.Database);
foreach (var current in enumerable)
Remove(current);
}
}
public List<string> GetKeyList()
{
var list = new List<string>();
var endPoints = Connection.GetEndPoints();
foreach (var endpoint in endPoints)
{
var server = Connection.GetServer(endpoint);
var enumerable = server.Keys(RedisCache.Database);
foreach (var redisKey in enumerable)
list.Add(redisKey);
}
return list;
}
protected virtual string Serialize(object serializableObject)
{
var jsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
};
return JsonConvert.SerializeObject(serializableObject, jsonSerializerSettings);
}
protected virtual T Deserialize<T>(string serializedObject)
{
if (serializedObject == null)
return default(T);
var jsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
};
return JsonConvert.DeserializeObject<T>(serializedObject, jsonSerializerSettings);
}
}
}
Redis Cache Aspect
using System;
using System.Linq;
using Cits.Portal.Core.CrossCuttingConcern.Caching.Redis;
using PostSharp.Aspects;
namespace Cits.Portal.Core.Aspects.Caching
{
[Serializable]
public class CacheAspectAttribute : MethodInterceptionAspect
{
private readonly int _cacheTimeOut;
public CacheAspectAttribute(int cacheTimeOut = 540)
{
_cacheTimeOut = cacheTimeOut;
}
public override void OnInvoke(MethodInterceptionArgs args)
{
var cacheManager = new RedisCacheManager();
if (args.Method.ReflectedType != null)
{
var methodFullName = $"{args.Method.ReflectedType.Namespace}.{args.Method.ReflectedType.Name}.{args.Method.Name}";
var arguments = args.Arguments.ToList();
var key = $"{methodFullName}({string.Join(",", arguments.Select(x => x?.ToString() ?? "<null>"))})";
if (cacheManager.IsAdd(key))
{
args.ReturnValue = cacheManager.Get<object>(key);
return;
}
base.OnInvoke(args);
cacheManager.Add(key, args.ReturnValue, _cacheTimeOut);
}
}
}
}
Our Module List Method which is cached
[CacheAspect]
public List<ModuleViewModel> GetListAsList()
{
var rowLogQuery = _rowLogService.GetListQueryable("Module");
var moduleQuery =
_moduleDal.GetQueryable(p => p.RowStateId != _rowState)
.Select(p => new ModuleViewModel
{
Id = p.Id,
Code = p.Code,
Name = p.Name,
IsActive = p.IsActive,
RowLogViewModel = rowLogQuery.FirstOrDefault(q => q.RowId.Equals(p.Id)),
RowStateId = p.RowStateId
}).ToList();
return moduleQuery;
}
Also These are my redis.windows.configs
bind 127.0.0.1
bind 141.11.11.212
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
databases 16
Also These are my redis.windows.service.configs
bind 127.0.0.1
bind 141.11.11.212
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
databases 16
Also I don't have redis auth password. I'm testing my app on remote server using remote servers browser but result the same.
Can you give me any suggestions about steps that I can find the issue/s?
And this the redis.server.log
[2252] 04 Aug 15:05:42.664 # Creating Server TCP listening socket 141.11.11.212:6379: bind: No error
[7504] 07 Aug 10:03:01.666 * Redis 3.2.100 (00000000/0) 64 bit, standalone mode, port 6379, pid 7504 ready to start.
[7504] 07 Aug 10:03:01.666 # Server started, Redis version 3.2.100
[7504] 07 Aug 10:03:01.666 * DB loaded from disk: 0.002 seconds
[7504] 07 Aug 10:03:01.666 * The server is now ready to accept connections on port 6379

Using Postal and Hangfire in Subsite

I have been trying to use Postal on my MVC5 site. When I host my webpage a subsite ie, http://localhost/Subsite I am receiving the error
The virtual path '/' maps to another application, which is not allowed
I have debugged it down to when the ControllerContext is being created the HttpContext isn't getting set correctly. Since I'm running Postal from Hangfire the HttpContext.Current is always null. Postal creates the ContollerContext using the code below.
ControllerContext CreateControllerContext()
{
// A dummy HttpContextBase that is enough to allow the view to be rendered.
var httpContext = new HttpContextWrapper(
new HttpContext(
new HttpRequest("", UrlRoot(), ""),
new HttpResponse(TextWriter.Null)
)
);
var routeData = new RouteData();
routeData.Values["controller"] = EmailViewDirectoryName;
var requestContext = new RequestContext(httpContext, routeData);
var stubController = new StubController();
var controllerContext = new ControllerContext(requestContext, stubController);
stubController.ControllerContext = controllerContext;
return controllerContext;
}
string UrlRoot()
{
var httpContext = HttpContext.Current;
if (httpContext == null)
{
return "http://localhost";
}
return httpContext.Request.Url.GetLeftPart(UriPartial.Authority) +
httpContext.Request.ApplicationPath;
}
How can I specify the UrlRoot so that instead of pulling the default of localhost to pull it based on my subsite?
I followed the directions here http://docs.hangfire.io/en/latest/tutorials/send-email.html to send my email. The method in the tutorial is below
public static void NotifyNewComment(int commentId)
{
// Prepare Postal classes to work outside of ASP.NET request
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));
var emailService = new EmailService(engines);
// Get comment and send a notification.
using (var db = new MailerDbContext())
{
var comment = db.Comments.Find(commentId);
var email = new NewCommentEmail
{
To = "yourmail#example.com",
UserName = comment.UserName,
Comment = comment.Text
};
emailService.Send(email);
}
}
I found the issue was that the FileSystemRazorViewEngine was not being used bty postal. To get the this to work I had to make sure that the FileSystemRazorViewEngine was the first engine in the available. I then removed it because I did not want it to be the default engine. Below is my updated method.
public static void NotifyNewComment(int commentId)
{
// Prepare Postal classes to work outside of ASP.NET request
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var eng = new FileSystemRazorViewEngine(viewsPath));
ViewEngines.Engines.Insert(0, eng);
var emailService = new EmailService(engines);
// Get comment and send a notification.
using (var db = new MailerDbContext())
{
var comment = db.Comments.Find(commentId);
var email = new NewCommentEmail
{
To = "yourmail#example.com",
UserName = comment.UserName,
Comment = comment.Text
};
emailService.Send(email);
ViewEngines.Engines.RemoveAt(0)
}
}
Below is another possible solution that I think is more elegant than above. It also resolves an issue that appears when accessing the MVC application while the background process is being executed.
public static void SendTypedEmailBackground()
{
try
{
var engines = new ViewEngineCollection();
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var eng = new FileSystemRazorViewEngine(viewsPath);
engines.Add(eng);
var email = new WebApplication1.Controllers.EmailController.TypedEmail();
email.Date = DateTime.UtcNow.ToString();
IEmailService service = new Postal.EmailService(engines);
service.Send(email);
}
catch(Exception ex)
{
throw ex;
}
}

Get a specific TestSuite by Id using the TFS API

I am trying to get a specific TestSuite using the TFS API for a TestPlan.
The TestSuite could exist anywhere within a TestSuite hierarchy, so, of course I could write a recursive function. I want something more efficient however.
Is there a method I am missing, or maybe a query that I could write?
If you already know the testSuiteId things are quite straightforward. You only need to know the name of your TeamProject teamProjectName:
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
namespace GetTestSuite
{
class Program
{
static void Main()
{
int testSuiteId = 555;
const string teamProjectName = "myTeamProjectName";
var tpc =
TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("http://tfsURI"));
var tstService = (ITestManagementService)tpc.GetService(typeof(ITestManagementService));
var tProject = tstService.GetTeamProject(teamProjectName);
var myTestSuite = tProject.TestSuites.Find(testSuiteId);
}
}
}
If you don't, you probably need to go for a solution similar to the one presented here (it's a S.Raiten post), where recursion does come into picture. Access to a testPlanId is assumed:
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
namespace GetTestSuite
{
class Program
{
static void Main()
{
int testPlanId = 555;
const string teamProjectName = "myTeamProjectName";
var tpc =
TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("http://tfsURI"));
var tstService = (ITestManagementService)tpc.GetService(typeof(ITestManagementService));
var tProject = tstService.GetTeamProject(teamProjectName);
var myTestPlan = tProject.TestPlans.Find(testPlanId);
GetPlanSuites(myTestPlan.RootSuite.Entries);
}
public static void GetPlanSuites(ITestSuiteEntryCollection suites)
{
foreach (ITestSuiteEntry suiteEntry in suites)
{
Console.WriteLine(suiteEntry.Id);
var suite = suiteEntry.TestSuite as IStaticTestSuite;
if (suite != null)
{
if (suite.Entries.Count > 0)
GetPlanSuites(suite.Entries);
}
}
}
}
}

Resources