I've searched without much success to the simplest (and yet working) example of an LDAP/AD Server for C#. Many libraries exist to connect to LDAP servers, but not the LDAP Server by itself (on C#).
I found however some information about it and even a post requesting a simple LDAP server that was answered "LDAP isn't simple"; and yet i read a lot of the RFC4511 and this sample code at GitHub Flexinet LDAP Server, but unfortunatly i don't have yet the knowledge to complete it's code.
My goal is not to make a fully functional LDAP server, but one that can at least do:
Serve as a login pool for softwares that allow it's users to be
registered and log on a AD/LDAP server (just check for login and
password for authentication).
Allow softwares like Outlook and Thunderbird to get a list of users (without passwords) with first and last name, e-mail address, phone number and department for contact list model.
No delete, add (or create), move, and other
functions are required since the main software that i aim to
integrate it with will do all the user and group management.
UPDATE
I'm trying to implement the Flexinet sample and adjust to that functionalities; as form of a question what should i do to change this function to prevent it from causing an exception (on the "var filter = searchRequest.ChildAttributes[6];" line it always breaks) when i call from a LDAP client software:
private void HandleSearchRequest(NetworkStream stream, LdapPacket requestPacket)
{
var searchRequest = requestPacket.ChildAttributes.SingleOrDefault(o => o.LdapOperation == LdapOperation.SearchRequest);
var filter = searchRequest.ChildAttributes[6];
if ((LdapFilterChoice)filter.ContextType == LdapFilterChoice.equalityMatch && filter.ChildAttributes[0].GetValue<String>() == "sAMAccountName" && filter.ChildAttributes[1].GetValue<String>() == "testuser") // equalityMatch
{
var responseEntryPacket = new LdapPacket(requestPacket.MessageId);
var searchResultEntry = new LdapAttribute(LdapOperation.SearchResultEntry);
searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.OctetString, "cn=testuser,cn=Users,dc=dev,dc=company,dc=com"));
searchResultEntry.ChildAttributes.Add(new LdapAttribute(UniversalDataType.Sequence));
responseEntryPacket.ChildAttributes.Add(searchResultEntry);
var responsEntryBytes = responseEntryPacket.GetBytes();
stream.Write(responsEntryBytes, 0, responsEntryBytes.Length);
}
var responseDonePacket = new LdapPacket(requestPacket.MessageId);
responseDonePacket.ChildAttributes.Add(new LdapResultAttribute(LdapOperation.SearchResultDone, LdapResult.success));
var responseDoneBytes = responseDonePacket.GetBytes();
stream.Write(responseDoneBytes, 0, responseDoneBytes.Length);
}
The code is on the github link.
Finally i made a fork of the Flexinet LDAP Server on #Sammuel-Miranda/LdapServerLib and with the author's support and some changes and adaptations i completed this implementation. It responds to the bind and search calls and works perfectly for Outlook and Thunderbird to use as a shared address book.
I did not implemente however any ADD/MODIFY/DELETE request (but would not be hard to do) since i don't need then.
I found on the RFC4511 the explanation on how the search works ... and i'm "kind" of understanding it, not very well - and i see that the method implemented on the GitHub from Flexinet LDAP Server only answer to bind and search requests of one single user (since it's only a example implementation).
The client is requesting diferent calls to verify capabilities, structure and other info before making the search request itself. So i'll implement it all, one by one.
Still, if any other lib (in C#) exists, and anyone know about, would be better than writing a hole new server. If my implementation works, i'll fork it on github and share.
Related
So I have a few different parse servers setup.
One server is just to capture error logs from various applications (I have a LOT out there) in nice uniformed database.
So I might have a specific standalone data migration tool that if it encounters an error, will write out the exception into this Error_log parse table/class. No problem there.
But, if I have an app that uses a Parse Database for itself, I have not been able to figure out how to let it work on it's own parse server configuration for it's own stuff, but write out error logs to this other Parse server instance.
Yes... I could go through the trouble of writing out something via the REST api just for writing out logs,but I am I trying to avoid that and stick with native parse APIs for the particular platform I am on because of the benefits that the APIs give over REST (like save eventually for the none .NET stuff).
EDIT
Some clarification was requested so here I go...
On the app side of things (c# for this example but the same holds true for iOS etc)… I do the usual initialization of the Parse client as such …
ParseClient.Initialize(new ParseClient.Configuration
{
ApplicationId = "MyAppID",
WindowsKey = "MyDotNetKey",
Server = "www.myparseserver.com/app1"
});
So for all calls to save a parse object go through that parse client connection
But what I need to do would be something like this ….
//Main App cloud database
ParseClient1.Initialize(new ParseClient.Configuration
{
ApplicationId = "MyAppID",
WindowsKey = "MyDotNetKey",
Server = "www.myparseserver.com/app1"
});
ParseClient2.Initialize(new ParseClient.Configuration
{
ApplicationId = "MyAppID",
WindowsKey = "MyDotNetKey",
Server = "www.myparseserver.com/errorcollection"
});
try{
ParseConfig config = null;
config = await ParseConfig.GetAsync().ParseClient1;
} catch (Exception ex){
ParseObject MyError = new ParseObject("Error_Log");
MyError["Application"] = "My First App-App2";
MyError["Error"] = ex.message;
await MyError.Save().ParseClient2;
}
Yes - this is all fake code... my point is I want to be able to have multiple ParseClient instances in one app.
Now... I can simply write a routine that writes out errors that resets the ParseClient.Initialization to the error parse server instance and then redo it back to the original (primary app data) instance when it's done... but that is just asking for trouble in a multi threaded environment and will cause conflicts if some other thread in the app goes to write out parse data right at the moment the error method resets the init.
If ParseClient were IDisposable I could probably do that using :
ParseClient ParseErrorServer = new ParseClient();
ParseErrorServer.ApplicationId = "hmmm";
ParseErrorServer.WindwosKey= "hmmm";
ParseErrorServer.Server= "www.hmmm.com/errorcollection";
using ParseErrorServer {
//Do The Work
}
Is that clear as mud yet? ;P
Without alteration I believe none of the Parse SDKs have the ability to initialise multiple instances.
In the iOS SDK for example, is possible to make a new instance (say with a different server url) upon restarting the app but you cannot have multiple. There has also been discussion on the iOS SDK about being able to change the configuration without restart but no one has implemented this yet.
We would happily review a PR for this, however it would require a major and complex overhaul as you would have to manage cache, users etc across multiple instances.
I am working on small application using the lync 2013 sdk. Is there any way provided in sdk where I can implement a functionality to allow user to upload his picture using any API provided in the SDK.
If it is possible then what and where is the best way to store it, if the users are configured in the active directory?
Waiting for a positive response from your side.
Regards
Amit
You can get a stream to the photo via the SDK using
var photoStream = Client.Self.Contact.GetContactInformation(ContactInformationType.Photo) as System.IO.Stream
And whilst you can read the stream you can't write to it as you are at this point looking at contact information from AD.
Kind of feels like you want to write something to change the photo in the photoThumbnails attribute of AD not in Lync.
Update as of 12/11/2013
The latest Lync update (Lync Client CU3 (November Update)) has the option to set a photo added back to the GUI.
Link to the KB Article
Link to the Download
Article with explanations and screenshots can be found here: Lync Client CU3 (November Update) – Show a picture from a website!.
Original Answer
Though this is a different problem, my answer to this question (Displaying a photo for an Application endpoint) is valid here as well:
Basicly, there is an option to set a user's photo to an URL, but it is no longer displayed in the Lync 2013 client interface (it was there in the Lync 2010 client). If you can get your code to publish the image to a web-accessible location, you could publish the URL to it and change your user picture that way.
For reference, the answer to the other question:
Publishing presence information (which includes photo settings) is done on the LocalEndpoint.LocalOwnerPresence. Both UserEndpoint and ApplicationEndpoint derive from LocalEndpoint, so this should be doable really.
The actual publishing gets slightly complex because there are a lot of different combinations of 'levels' to publish on:
First, there are a bunch of InstanceID values that you need to know about, read up on them here: Presence data source and category instance ID
Second, there is a value for who this presence applies to, see Microsoft.Rtc.Collaboration.Presence.PresenceRelationshipLevel. Don't publish on Unknown, you'll get an exception.
public enum PresenceRelationshipLevel
{
Unknown = -1,
Everyone = 0,
External = 100,
Colleagues = 200,
Workgroup = 300,
Personal = 400,
Blocked = 32000,
}
You need to publish a PresenceCategoryWithMetaData for the user photo properties, which is part of container 0x5, "Presentity information".
var photoPresence = new PresenceCategoryWithMetaData(
0x5, // The container id
(int)PresenceRelationshipLevel.Everyone,
new ContactCard(0x5) // Same container ID again
{
IsAllowedToShowPhoto = true,
PhotoUri = "<uri to your photo here"
});
You can set an ExpiryPolicy on this object too, should be self explainatory really. Then publish this presence object on your endpoint:
Endpoint.LocalOwnerPresence.BeginPublishPresence(new[] { photoPresence }, cb => {
Endpoint.LocalOwnerPresence.EndPublishPresence(cb);
}, null);
And that should do it, really. I ended up explicitly publishing to all relationship levels because it didn't cascade the data as logically expected.
I've found several different questions about this error, but none of them seem to outline my scenario.
I am creating a website that pulls in tweets from our company's Twitter account, and displaying them on a social wall. I am using C# asp.NET webforms. The C# code uses a Linqtotwitter library to handle the authentication and the "tweet pulling." It grabs the tweets and dumps them onto an aspx file as a big long string of json. We then have a jquery script that reads through the json and displays the tweets on the page nice and pretty like.
The code currently works perfect on my dev box. But when I push the code up to production I get this .NET error:
The remote certificate is invalid according to the validation procedure
I'll provide my code in a bit here, but first let me give you a little background. I have no idea if this information would be relevant or not, but who knows. This website is actually part of a larger project to fit several tiny one page microsites that we get from marketing onto one server to reduce the overhead they cause. These microsites can all have a different host name, but they point to the same IP address. An httpmodule lives on that server, and intercepts all requests coming in, and redirects them to an appropriate sub folder depending on the host name.
From the research that I've done, it seems that SSL is tied into this error quite a bit. I'm still pretty new to the IT world, and I'm learning more about SSL as this troubleshooting goes on. The server these microsites live on does have a few SSL certificates on it, and one of the microsites uses SSL, but not the website I'm currently working on. But since they both share the same IP address in that sense they kind of ARE the same website.
This is the C# LinqtoTwitter code:
private SingleUserAuthorizer auth;
private TwitterContext twitterCtx;
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "application/json";
auth = new SingleUserAuthorizer
{
Credentials = new SingleUserInMemoryCredentials
{
ConsumerKey =
ConfigurationManager.AppSettings["twitterConsumerKey"],
ConsumerSecret =
ConfigurationManager.AppSettings["twitterConsumerSecret"],
TwitterAccessToken =
ConfigurationManager.AppSettings["twitterAccessToken"],
TwitterAccessTokenSecret =
ConfigurationManager.AppSettings["twitterAccessTokenSecret"]
}
};
if (auth.IsAuthorized)
{
twitterCtx = new TwitterContext(auth);
var tweetResponse =
(from tweet in twitterCtx.Status
where tweet.Type == StatusType.User &&
tweet.ScreenName == "OurProfile" &&
tweet.IncludeRetweets == true
select tweet)
.ToList();
Results.Text = twitterCtx.RawResult;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (twitterCtx != null)
{
twitterCtx.Dispose();
twitterCtx = null;
}
}
Does anyone have any ideas of what could be the problem here? Like I said, I'm still pretty new, and I'm at a loss here even how to troubleshoot this issue beyond Google. Could it be something where our server can't verify that Twitter's SSL certificate is from a trusted source? Let me know if I can provide any more information or any more code. Thanks for your time and for reading through my post!
I am trying to access data remotely from sharepoint 2010 site using client object model. For some restrictions I am not able to use CAML query even if I use I am not able to filter for proper audiences based on user login (if you can help me regarding the CAML query is also fine :: i do not know how to get current user audience name and all audiences using CAML/client object model. This code sits on the mobile site and calling the share point site as shown in my code). This following code works good but not able to get the content from the webpart. Can someone help regarding this.
using (ClientContext ctx = new ClientContext("https://mysite.com/Pages/Default.aspx"))
{
ctx.ExecutingWebRequest += new EventHandler<WebRequestEventArgs> (clientContext_ExecutingWebRequest);
File home=ctx.Web.GetFileByServerRelativeUrl("/Student/Pages/default.aspx");
//get the web part manager
Microsoft.SharePoint.Client.WebParts.LimitedWebPartManager wpm = home.GetLimitedWebPartManager(Microsoft.SharePoint.Client.WebParts.PersonalizationScope.Shared);
IEnumerable<Microsoft.SharePoint.Client.WebParts.WebPartDefinition> wpds = null;
//create the LINQ query to get the web parts from
//the web part definition collection
wpds = ctx.LoadQuery(wpm.WebParts.Include(wp => wp.Id,wp => wp.WebPart));
//load the list of web parts
ctx.ExecuteQuery();
//enumerate the results
foreach (Microsoft.SharePoint.Client.WebParts.WebPartDefinition wpd in wpds)
{
string title= wpd.WebPart.Title;
Microsoft.SharePoint.Client.WebParts.WebPart wpart = wpd.WebPart;
????? How to render and receive the data (looking for the same data When you browse the site with the browser)
}
Code continues...
I am also struggling with this issue. It really looks like this is not possible with client object model. Actually i've asked it to some SharePoint staff member at Build Conference 2012.
But, with the SharePoint Designer it's actually possible to download the wanted WebPart. Fiddler may come handy to track down which service will deliver you the bits.
Take a look at this post here on SharePoint StackExchange
Unfortunately the post will not give you any concrete way to solve it.
Wish you good luck!
Update
Thanks to a comment by #IvanL, it turns out that the problem is Google specific. I have since tried other providers and for those everything works as expected. Google just doesn't seem to send claims information. Haven't yet been able to figure out why or what I need to differently to get Google to send it.
A wild stab in the dark says it may be related to the realm being defaulted to http://:/ as I have seen an answer by Andrew Arnott that Google changes the claimed identifier for the same account based on the realm passed with the authentication request.
Another possibly important tidbit of information: unlike many of the examples that can be found around the web for using dotnetopenauth, I am not using a "simple" textbox and composing the openIdIdentifier myself, but I am using the openID selector and that is providing the openIdIdentifier passed to the ValidateAtOpenIdProvider. (As per the Adding OpenID authentication to your ASP.NET MVC 4 application article.)
Question is: why is IAuthenticationResponse.GetExtension() always returning null when using Google as the openId provider, when otherwise all relevant gotcha's with regard to Google (Email requested as required, AXFetchAsSregTransform, etc) have been addressed?
Original
I am struggling with getting DotNetOpenAuth to parse the response returned from the provider. Followed the instructions of Adding OpenID authentication to your ASP.NET MVC 4 application up to the point where the login should be working and a login result in a return to the home page with the user's name (nick name) displayed at the top right. (That is up to "The user should at this point see the following:" just over half way down the article).
I am using Visual Studio Web Developer 2010 Express with C#. DotNetOpenAuth version is 4.0.3.12153 (according to the packages.config, 4.0.3.12163 according to Windows Explorer).
My web.config was modified following the instructions in Activating AXFetchAsSregTransform which was the solution for DotNetOpenId - Open Id get some data
Unfortunately it wasn't enough to get it working for me.
The openid-selector is working fine and resulting in a correct selection of the openid provider. The authentication request is created as follows:
public IAuthenticationRequest ValidateAtOpenIdProvider(string openIdIdentifier)
{
IAuthenticationRequest openIdRequest = openId.CreateRequest(Identifier.Parse(openIdIdentifier));
var fields = new ClaimsRequest()
{
Email = DemandLevel.Require,
FullName = DemandLevel.Require,
Nickname = DemandLevel.Require
};
openIdRequest.AddExtension(fields);
return openIdRequest;
}
This all works. I can login and authorize the page to receive my information, which then results in a call to GetUser:
public OpenIdUser GetUser()
{
OpenIdUser user = null;
IAuthenticationResponse openIdResponse = openId.GetResponse();
if (openIdResponse.IsSuccessful())
{
user = ResponseIntoUser(openIdResponse);
}
return user;
}
openIdResponse.IsSuccessful is implemented as an extension method (see linked article):
return response != null && response.Status == AuthenticationStatus.Authenticated;
and always is successful as the ResponseIntoUser method is entered:
private OpenIdUser ResponseIntoUser(IAuthenticationResponse response)
{
OpenIdUser user = null;
var claimResponseUntrusted = response.GetUntrustedExtension<ClaimsResponse>();
var claimResponse = response.GetExtension<ClaimsResponse>();
// For this to work with the newer/est version of DotNetOpenAuth, make sure web.config
// file contains required settings. See link for more details.
// http://www.dotnetopenauth.net/developers/help/the-axfetchassregtransform-behavior/
if (claimResponse != null)
{
user = new OpenIdUser(claimResponse, response.ClaimedIdentifier);
}
else if (claimResponseUntrusted != null)
{
user = new OpenIdUser(claimResponseUntrusted, response.ClaimedIdentifier);
}
else
{
user = new OpenIdUser("ikke#gmail.com;ikke van ikkenstein;ikke nick;ikkeclaimedid");
}
return user;
}
My version above only differs from the code in the linked article by my addition of the final else block to ensure that I always get the home page with a user name and a logoff link displayed (which helps when trying to do this several times in succession).
I have tried both Google and Yahoo. Both authenticate fine, both return an identity assertion as logged by the WebDev server. However, GetUntrustedExtenstion and GetExtension always return null. I always get to see "ikke nick" from the last else, never the name I actually used to authenticate.
I am at a loss on how to continue to try and get this to work. It probably is some oversight on my part (I am an experienced developer but just started dipping my toes in C# and web front-end development), and I can't see it.
Any and all suggestions on how to proceed / debug this are very much welcome.
Are you using Google as OpenId provider to test your solution against? Because Google has/had the habit of including the Claims only the first time you authenticate the application. So perhaps try using a fresh google account and see if that works?
Sorry for the slow response, doing a big migration at a client this week :-) Glad that this little comment resolved your issue.