0

This may be a silly question, but is it possible to obtain GSSAPI token for current logged in user from Active Directory?

I have a simple library that connects to server. I can pass user name, password and domain name or GSS Token (base64). For now first method works for me, but it is annoying to users that they must put their password.

I couldn't find any informations about GSSAPI and it's integration with Active Directory.

Is it possible in C#?

Some more informations based on @Harvey Kwok comment: Library is called Altair COM and it is used for document management

Here is some API reference about Login with GSS:

HRESULT LoginGSS(
     [in] VARIANT *token,
     [in] VARIANT_BOOL forceCreateNew,
     [out,retval] VARIANT *retToken)

And below is sample usage in VB:

Dim token(tokensize) As Byte 'token size-1
’fill token buffer
...
Dim outToken() As Byte
outToken = altair.LoginGSS(token,True)
'if GetLastStatus == AXAPI_ALTAIR_LOGIN_CONTINUE then
'outToken contains return GSS API token

And VC++ usage

SAFEARRAYBOUND sab[1];
sab[0].lLbound=0;
sab[0].cElements=tokensize;
SAFEARRAY *sa;
sa=SafeArrayCreate(VT_UI1,1,sab);
unsigned char HUGEP *buf=NULL;
SafeArrayAccessData(sa,(void HUGEP**)&buf);
//fill token buffer
...
SafeArrayUnaccessData(sa);
v.vt=VT_ARRAY|VT_UI1;
v.pparray=sa;
VARIANT vOut;
pAltair->LoginGSS(&v,true,&vOut);
SafeArrayDestroy(sa);
'if GetLastStatus == AXAPI_ALTAIR_LOGIN_CONTINUE then
'outToken contains return GSS API token

This are all informations that I have.


I found some code snippet showing login procedure:

byte[] token;
token = Convert.FromBase64String(tbToken.Text);
Object o;
o = (Object)token;
Program.altair.LoginGSS(ref o, true);
if ((AXAPILib.AxAPIStatus)altair.GetLastStatus()==AXAPILib.AxAPIStatus.AxAltairLoginOK)
{
    //login ok
}

But I must enter that token and I'm still trying to generate it for current user.

Misiu
  • 4,738
  • 21
  • 94
  • 198
  • What simple library is it? What token does it take? What GSS token are you talking about? I assume it's the returned context token from the GSSAPI? What GSSAPI are you using? Are you using MIT GSSAPI or are you using Windows SSPI? – Harvey Kwok Dec 05 '12 at 06:50
  • @HarveyKwok - I've edited my question and added some API reference. I'm not using currently any GSSAPI. As I write right now usem must log-in to his computer (and to domain of course) and then when he starts my application he must enter his password second time, I would like to avoid that. My only option is that GSSAPI but I have no ideas how to use it :/ – Misiu Dec 05 '12 at 10:12
  • @Misiu did you manage to achieve this? I need to connect to a LDAP server with GSSAPI authentication. Would you be able to provide some sample code in C#? couldn't find anything online – AnOldSoul Jun 04 '17 at 02:19
  • @mayooran unfortunately not. System that required this was outdated and lack of LDAP integration was another reason to replace it. After year or so we replaced it and this functionality wasn't needed. Sorry I can't help. – Misiu Jun 05 '17 at 06:48
  • @Misiu oh that's okay. Thanks mate! – AnOldSoul Jun 05 '17 at 08:20

2 Answers2

2

Don't waste your time. Use SSPI with P/Invoke in C#.

Michael-O
  • 18,123
  • 6
  • 55
  • 121
  • I know that this may sounds a dumb question, but SSPI implements GSS-API? – Misiu Dec 06 '12 at 09:11
  • Yes, that is correct. SSPI is the Windows proprietary implementation of the GSS-API. – Michael-O Dec 06 '12 at 09:57
  • 1
    Is it possible that You could add come code? I just need to initialize that token and send it to server using my API. – Misiu Dec 06 '12 at 14:33
  • Godeke's reference is quite good. I would start with the provided source code. – Michael-O Dec 06 '12 at 19:37
  • I find it very strange that there is no reference API on Microsoft's refernce .NET language. – Michael-O Dec 06 '12 at 19:38
  • 1
    that's right, there is no reference for .NET and for someone not experience with C++ it is hard to get this one working. I was searching on P/Invoke, but number of lines in sample is...enormous... I just need token for current AD user so that I can perform login to that document management server using provided API. – Misiu Dec 07 '12 at 09:39
  • 1
    What about this class http://msdn.microsoft.com/en-us/library/system.servicemodel.security.sspisecuritytokenprovider.aspx ? – Michael-O Dec 07 '12 at 14:12
  • What I have for now is `var credentials = CredentialCache.DefaultNetworkCredentials;var tokenprovider = new SspiSecurityTokenProvider(credentials,false,false);var token = tokenprovider.GetToken(new TimeSpan(1,0,0,0));` This returns me my token (if I'm right) but how to turn it into base64 array? I've added some code to my question showing login function from sample. – Misiu Dec 07 '12 at 15:06
  • You have a byte array and have to convert that to base64 http://dotnet-snippets.de/dns/byte---base64-und-base64---byte-SID138.aspx http://www.motobit.com/help/scptutl/cm435.htm http://msdn.microsoft.com/en-us/library/dhx0d524.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1 send that over the wire. Receive the mutual (response) token, validate and you have the context established. – Michael-O Dec 07 '12 at 15:38
  • My problem is how to convert `System.IdentityModel.Tokens.SecurityToken` into byte array or how to get byte array from that token. – Misiu Dec 07 '12 at 16:01
  • What about this method: http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.kerberosrequestorsecuritytoken.getrequest.aspx ? – Michael-O Dec 07 '12 at 18:48
0

Microsoft has an example of using SSPI in Managed C++ (which is easy to then call from C#) here: http://msdn.microsoft.com/en-us/library/ms973911.aspx

Why not write it in C#? I experimented with writing the assembly in C# as well as Managed C++. I quickly discovered a basic trade-off: did I want to work with unmanaged code like the SSPI in a managed language (like C#) or did I want to write it in C++ and use managed extensions to interface to the .NET world?

With SSPI there are a number of functions with complex parameters. This includes lots of pointers, (nested) structures, and so on. Writing the assembly in C# means that having to declare managed versions of the SSPI function parameters (all of those complex types) and then making sure they're properly pinned in memory when passing them to the unmanaged functions.

Writing the assembly in managed C++ means dealing with the unmanaged types in their native environment. You don't necessarily have to worry about pinning and you don't have to re-declare types (just pull in the appropriate header files).

When building Microsoft.Samples.Security.SSPI, I found it was easier to do the job in Managed C++. All of the complex types are kept in the unmanaged world; the unmanaged APIs are dealt with in their native C environment. Managed C++ provides a great way to bridge the gap between the unmanaged/managed world.

Your mileage may vary and choice is going to depend on the APIs being used. But with SSPI, managed extensions make more sense than a higher level language like C#.

Community
  • 1
  • 1
Godeke
  • 16,131
  • 4
  • 62
  • 86
  • Thanks for replay, but could You please add some sample code? I've downloaded code from Your link, but most of it is in C++, could this be done without C++? Using P/Invoke maybe? I would really be grateful for some code :) – Misiu Dec 06 '12 at 13:43