How to get Alfresco login ticket without user pass

2019-04-01 05:18发布

I'm writing a DLL that has function for getting Alfresco login ticket without using user password, using only a user principal name (UPN). I’m calling alfresco REST API service /wcservice. I use NTLM in Alfresco.

I’m impersonating users using WindowsIdentity constructor as explained here http://msdn.microsoft.com/en-us/library/ms998351.aspx#paght000023_impersonatingbyusingwindowsidentity. I checked and user is properly impersonated (I checked WindowsIdentity.GetCurrent().Name property).

After impersonating a user, I try to make HttpWebRequest and set its credentials with CredentialsCache.DefaultNetworkCredentials. I get the error:

The remote server returned an error: (401) Unauthorized.
   at System.Net.HttpWebRequest.GetResponse()

When I use new NetworkCredential("username", "P@ssw0rd") to set request credentials, I get Alfresco login ticket (HttpStatusCode.OK, 200).

Is there any way that I can get Alfresco login ticket without user password?

Here is the code that I'm using:

private string GetTicket(string UPN) {
 WindowsIdentity identity = new WindowsIdentity(UPN);
 WindowsImpersonationContext context = null;

 try {
  context = identity.Impersonate();

  MakeWebRequest();
 }
 catch (Exception e) {
  return e.Message + Environment.NewLine + e.StackTrace;
 }
 finally {
  if (context != null) {
   context.Undo();
  }
 }
}

private string MakeWebRequest() {
 string URI = "http://alfrescoserver/alfresco/wcservice/mg/util/login";


 HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;

 request.CookieContainer = new CookieContainer(1);

 //request.Credentials = new NetworkCredential("username", "p@ssw0rd"); // It works with this
 request.Credentials = CredentialCache.DefaultNetworkCredentials;  // It doesn’t work with this
 //request.Credentials = CredentialCache.DefaultCredentials;    // It doesn’t work with this either

 try {
  using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) {
   StreamReader sr = new StreamReader(response.GetResponseStream());

   return sr.ReadToEnd();
  }
 }
 catch (Exception e) {
  return (e.Message + Environment.NewLine + e.StackTrace);
 }
}

Here are records from Alfresco stdout.log (if it helps in any way):

17:18:04,550  DEBUG [app.servlet.NTLMAuthenticationFilter] Processing request: /alfresco/wcservice/mg/util/login SID:7453F7BD4FD2E6A61AD40A31A37733A5
17:18:04,550  DEBUG [web.scripts.DeclarativeRegistry] Web Script index lookup for uri /mg/util/login took 0.526239ms
17:18:04,550  DEBUG [app.servlet.NTLMAuthenticationFilter] New NTLM auth request from 10.**.**.** (10.**.**.**:1229)
17:18:04,566  DEBUG [app.servlet.NTLMAuthenticationFilter] Processing request: /alfresco/wcservice/mg/util/login SID:7453F7BD4FD2E6A61AD40A31A37733A5
17:18:04,566  DEBUG [web.scripts.DeclarativeRegistry] Web Script index lookup for uri /mg/util/login took 0.400909ms
17:18:04,566  DEBUG [app.servlet.NTLMAuthenticationFilter] Received type1 [Type1:0xe20882b7,Domain:<NotSet>,Wks:<NotSet>]
17:18:04,566  DEBUG [app.servlet.NTLMAuthenticationFilter] Client domain null
17:18:04,675  DEBUG [app.servlet.NTLMAuthenticationFilter] Sending NTLM type2 to client - [Type2:0x80000283,Target:AlfrescoServerA,Ch:197e2631cc3f9e0a]

2条回答
别忘想泡老子
2楼-- · 2019-04-01 05:27

I've solved the problem!

I believe that we had a double-hop problem.

This is what had to be done to solve this problem:

  1. User that runs my DLL must be Windows Server 2003 domain user
  2. Service that uses my DLL must have registered Service Principal Name in Domain controller with user that runs it (user that runs my DLL)
  3. User that runs my DLL must not have Account is sensitive and cannot be delegated option selected in Domain controller
  4. User that runs my DLL must have Trust this user for delegation to any service (Kerberos only) or Trust this user for delegation to specified services only option selected in Domain controller (if the user is in Windows Server 2003 functional domain this option is available only when you register Service Principal Name with this user)
  5. User that runs my DLL must have TrustedToAuthForDelegation user account control (UAC) set to true
  6. Computer that runs service that uses my DLL must have Trust computer for delegation to any service (Kerberos only) or Trust computer for delegation to specified services only option selected in Domain Controller

This all (and more) is explained in Microsoft document Troubleshooting Kerberos Delegation. It contains:

  • checklist for Active Directory,
  • checklist for Client application,
  • checklist for Middle tier,
  • checklist for Back-end

plus

  • configuration examples for common scenarios.

Setting TrustedToAuthForDelegation user account control (UAC) is done in PowerShell by Active Directory cmdlet explained here.

You can read more about Windows Authentication in ASP.NET 2.0.

Of course, Alfresco must have Kerberos login enabled.

查看更多
劫难
3楼-- · 2019-04-01 05:38

I think that it is not possible for Alfresco. Only if you use special authentication subsystem where exists this 'impersonal' user.

Try this, because 'guest' user is transversal for all subsystem authentication.

request.Credentials = new NetworkCredential("guest", "guest");

And the URI, something like this:

string URI = "http://alfrescoserver/alfresco/s/api/login or whatever you propose.

Good luck. Paco

查看更多
登录 后发表回答