Windows Authentication

Posted by Community Admin on 03-Aug-2018 05:58

Windows Authentication

All Replies

Posted by Community Admin on 23-May-2011 00:00

Hi,

I've been holding off on upgrading to 4 from 3.7 because currently we have windows authentication enabled and 4.0 didn't support this.

I noticed with 4.1 you know allow auto login with windows authentication if you have AD enabled:
www.sitefinity.com/.../enabling-windows-authentication.aspx

While I didn't really want to turn on AD authentication I'm happy to do so if it works.  My main problem is going to be: Does Sitefinities LDAP support searching/authenticating accross the root and Child domains and if so how would I do this.

We have about 6 or 7 active domains on our network.

Thank you for any help you can provide.

Regards
Byron

Posted by Community Admin on 23-May-2011 00:00

Hi Byzza,

If you mean Single Sign On, by authenticating over several domains, this is still not supported out of the box. It could be done with a custom implementation on subdomains, because this will allow you to easily pass the cookies from the cookie collection. There is a method of the SecurityManager that you can use - AuthenticateUser. AuthenticateUser validates the user - password and username - password is encrypted and compared with the input you use. Then the username and passwordare compared. If the user is valid  we get the user , verify the ip and last login request SetAuthenticationCookie was made internal, so to authenticate a user you should use AuthenticateUser method. Basically we create the cookie with the cookie path, domain and whether ssl is required. Then we add the cookie to the FormsAuthenticationTicket, decrypt it and set Expires property of the cookie. To decrypt the password we use the decryptionKey inside App_Data/Sitefinity/Configurations/SecurityConfig.config

<securityConfig authCookieName=".SFAUTH-/" rolesCookieName=".SFROLES-/" validationKey="279EB02E02B8322864837AA092A6384F61E267310BD526CA5AA7BA61B7ECA17071022B3F025FBA05CB390ECE4CF2B7D93F377CD50085355795AF69C89AA347C2" decryptionKey="DF845BFCA7B2A84D0649DA8F2C033715772EA183D8A1A2E7072082CD0482DBDE" loggingCookieName=".SFLOG-/">

Here is a sample code that should authenticate a user from one application to another. Note that this will work only if you are on the same domain name, because the cookies are not valid between different domains.  If you are going to use different domains you should have a common repository where you should save the cookies. You should also add another parameter to the request - some ID that will take care of the expiration of this cookie for the current request, so that this will not allow to others to use it.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
  
public partial class Default8 : System.Web.UI.Page
    protected void Page_Load(object sender, EventArgs e)
    
        var membershipProvider = "";
        var userName = "admin";
        var password = "admin@2";
        var rememberMe = true;
  
        if (AuthenticateRequest(membershipProvider, userName, password, rememberMe))
        
            Response.Redirect("http://localhost:4000/Sitefinity/Pages");
        
        else
        
            Response.Write("Try Again.");
        
    
  
        public  string InvokeWebMethod(string serviceUrl, string methodName, string httpMethod, byte[] data)
        
          
            var request = (HttpWebRequest)WebRequest.Create(String.Concat(sitefinityHost, serviceUrl, methodName));
            request.Method = httpMethod;
            request.ContentType = "application/json";
            request.CookieContainer = new CookieContainer();
  
            if (cookies != null)
            
                foreach (Cookie cookie in cookies)
                    if (!cookie.Expired)
                        request.CookieContainer.Add(cookie);
            
  
            if (data != null)
            
                request.ContentLength = data.Length;
                using (var writer = request.GetRequestStream())
                
                    writer.Write(data, 0, data.Length);
                
            
  
              
            using (var response = (HttpWebResponse)request.GetResponse())
            
  
                // HERE WE GET THE RESPONSE AND ADD THE COOKIES TO IT.
                cookies = response.Cookies;
                using (var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                
                    // GET THE cookies AND ADD COOKIES NAME AND VALUE TO THE CURRENT RESPONSE!
                    var name = "";
                    var value = "";
                    Response.Cookies.Add(new HttpCookie(name, value));
                    return reader.ReadToEnd();
                
  
                
  
            
        
  
        public  bool Logout()
        
            return InvokeWebMethod(usersServiceUrl, logoutCurrentUserMethod, "GET", null) == "true";
        
  
        public  bool Logout(byte[] credentials)
        
            return InvokeWebMethod(usersServiceUrl, logoutUserWithCredentialsMethod, "POST", credentials) == "true";
        
  
        private bool AuthenticateRequest(string membershipProvider, string userName, string password, bool rememberMe)
        
              
            var jsonData = String.Format(credentialsFormat, membershipProvider, userName, password, rememberMe.ToString().ToLower());
            var credentials = Encoding.UTF8.GetBytes(jsonData);
            string result = InvokeWebMethod(usersServiceUrl, authenticateMethod, "POST", credentials);
            switch (result)
            
                case "0":
                    return true;
                case "3":
                case "6":
                case "9":
                    Response.Write("There is a user with the same credentials logged in the system form another application or browser.\r\n It will be logged out");
                    if (Logout(credentials))
                            return InvokeWebMethod(usersServiceUrl, authenticateMethod, "POST", credentials) == "0";
                    return false;
                default:
                    return false;
            
        
  
          
  
        private const string credentialsFormat = @"
        
            ""MembershipProvider"":""0"",
            ""UserName"":""1"",
            ""Password"":""2"",
            ""Persistent"":3
        ";
        private static CookieCollection cookies;
        private const string usersServiceUrl = "/Sitefinity/Services/Security/Users.svc/";
        private const string authenticateMethod = "Authenticate";
        private const string logoutCurrentUserMethod = "Logout";
        private const string logoutUserWithCredentialsMethod = "LogoutCredentials";
        private const string logoutOtherUserMethos = "Logout/0/1";
        private const string sitefinityHost = "http://localhost:4000";
  
         
      


Greetings,
Ivan Dimitrov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 24-May-2011 00:00

Hi,
Thank you for such a quick response.

I don't think that is actually what I'm after.  Please correct me if I'm wrong but what you have there is to allow a user to be authenticated on:
http://domain1.mycompany.com
http://domain2.mycompany.com
http://domain3.mycompany.com
so if they log into one they log into all 3 so they don't have to log in again?

If so, not that is not what I'm after.

We have an intranet here (eg http://intranet/) which is avalible from all our sites around the world via VPN.  Each of the Major sites have their own Active directory Server, and such their own Domain.  So a user at head office would log in with the username "HeadOffice\user1"  where as a user at another site might log in with the username "Site123\user2"

The HeadOffice domain is the master/primary domain and all the other domains are linked into it so that they all work together and can see each other.

Now I think I worked out in theroy I could create a whole heap of membership providers, one for each domain and the user just selects the domain they need to sign in to, BUT because I'm trying to avoid the whole sign in all together and use Windows Authentication I assume I must have only one LDAP membership provider active.

So could you please let me know if Sitefinity would be able to support this setup with Windows authentication and how I can set it up.

--------------------------------------
On another note though, just to try and see how the LDAP worked (this is the first Time I've ever used LDAP)  I decided to try and set it up with just HeadOffice, just to see if it would work if it could even connect, and so far nothing I try will work.  I've spoken to our network admin, and I've used a program called "LDAP Browser" to mimic the settings in Sitefinity, but no matter what settings I try when I go to users none are returned from AD.

I've attached a screen shot of the final Config I tried.
the port I have set in the screen shot is to a Global list which should have all the domains together according to the network admin (just experimenting with both), but I've tried the normal port as well just for Head office.


If you could please help on either issue that would be great.

Thank you
Byron Boardman

Posted by Community Admin on 24-May-2011 00:00

Ok, so i'm still having the mulitple domain issue still (well haven't started too look into it yet), but as far as the second issue goes I finally got SF connected to LDAP and under user accounts I can see the full list under our main domain, but when I follow the instructions here:
http://www.sitefinity.com/documentation/installation-and-administration-guide/system-settings/enabling-windows-authentication.aspx

And change the web.config from

<authentication mode="Forms"/>
to
<authentication mode="Windows"/>

I'm now getting this error:
 

Server Error in '/SPTest' Application.

Invalid full name format.
Parameter name: windowsIdentity.Name

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: Invalid full name format.
Parameter name: windowsIdentity.Name

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[ArgumentException: Invalid full name format.
Parameter name: windowsIdentity.Name]
   Telerik.Sitefinity.Security.WindowsIdentity.LoadUser(WindowsIdentity windowsIdentity) +404
   Telerik.Sitefinity.Security.WindowsIdentity..ctor(WindowsIdentity windowsIdentity) +26
   Telerik.Sitefinity.Security.SecurityManager.BuildIdentity(HttpContextBase context) +697
   Telerik.Sitefinity.Security.SecurityManager.BuildPrincipal(HttpContextBase context) +103
   Telerik.Sitefinity.Security.SecurityManager.AuthenticateRequest(HttpContextBase context) +380
   Telerik.Sitefinity.Web.SitefinityHttpModule.Context_AuthenticateRequest(Object sender, EventArgs e) +18
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1



I can't seem to get around this no matter what I try.

Posted by Community Admin on 25-May-2011 00:00

Byzza - 

I am seeing similar error messages after following the instructions listed in that link - but only for a few users so far - others are fine.

So I ask...

What can we look at to see why certain users are getting the above message?

Also - what happens when a user can't be authenticated automatically?  It seems as though they go to my defined login page - is this correct?  ---- EDIT: This was because I still had some Authentication-related code in my .MASTER page for generating some Session variables

Posted by Community Admin on 26-May-2011 00:00

Hi Daniel,

I'm not even sure where to start, I only have 3 users in that DB and all of them have the same problem.

Posted by Community Admin on 26-May-2011 00:00

Hi Byzza,

We thrown this error Invalid full name format.", "windowsIdentity.Name" when the windowsIdentity.Name is not in format Domain\USER

I am not able to replicate this issue locally with LDAP and Windows authentication. Can you check what the the identity name?

System.Web.HttpContext.Current.User.Identity.Name


All the best,
Ivan Dimitrov
the Telerik team

Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 26-May-2011 00:00

OK - I figured out....  Now keep in mind I am using this current SF installation in an Intranet context - NOT public facing web.

The instructions to have people auto-login to the backend does not work properly for me.  The /Sitefinity/Services directory must be under Anonymous authentication according to the popups I see because of the WCF stuff.

At first I tried turning off FORMS and putting WINDOWS authentication on for everything and I got the error above. 

My current setup is this in IIS7 to achieve Windows Authentication properly on Front End ( - but still cannot get AUTO-Login to backend):
IIS Settings
Site - Windows Authentication ON
Site/Sitefinity/Services - Windows Authentication OFF Anonymous Authentication ON
FORMS authentication OFF totally

Windows File System
Site - Read/Write permissions to INTRANET_GROUP - an AD group with has all of my Intranet users in it

I now have Windows Authentication for the Front End, plus I have an LdapUsers Membership provider from which I assign Backend and other Default Roles to my backend users.  These users must logon manually to the Backend, but can use their NT logon credentials.

The ultimate goal would be for the backend to be seamless for those logged in users that have backend access, but this setup works for now.

Posted by Community Admin on 26-May-2011 00:00

I thought I had this working.... until I went in to actually do editting in the backend - but because the webservices are all over the place - I keep getting yelled at about not being Anonymous!!!!

I don't get it.  The instructions say to change to the authenitcation method to WINDOWS - but the services on the backend NEED Anonymous??? How to overcome this?

This is soooooooooo frustrating.

Posted by Community Admin on 26-May-2011 00:00

Sorry - Not trying to bump this - but I am finding lots of information about using Windows Authentication in WCF Services.... So this should be possible.

The core issue preventing my Windows authentication from working right is because the WCF calls fail in a non-anonymous context.

Posted by Community Admin on 28-May-2011 00:00

I'm not sure if this would help, but I did some research and found the following links - hope they might help:

http://www.codeproject.com/KB/WCF/WCFBasicHttpBinding.aspx?msg=3104044

http://social.msdn.microsoft.com/forums/en-US/wcf/thread/442be0c8-309e-4000-9311-57189ae7a900/

Posted by Community Admin on 29-May-2011 00:00

Thanks Lupi.

I went through all of those steps and have read those articles while working through this issue, but thanks for making sure that I know how to Google - ;)  I know some people choose to be lazy and not find things for themselves.

First of all - the main web service for the CMS CRUD actions uses webHttpBinding - which can also use Transport authentication.  There are also basicHttpBinding services, but the big issue area is the webHttpBinding one - the ones that handle the JSON data.

The problem is that we cannot change the authentication scheme on the services in the Service's web.config - at least as far as I have been able to figure out.  You can do all of the work in the world on the site's web.config - but if you can't let the service know that it is using Windows authentication - the service will still send a 500 response.

This is where the real hangup is.  The WCF service doesn't need to care if it is receiving credentials at all.  It can choose to ignore them if it chooses, BUT it has to be setup to understand that credentials are in fact being presented to it in the first place.

If this hurdle can be cleared, I have a feeling that Windows authentication can work on SF4.1

Posted by Community Admin on 30-May-2011 00:00

Hi,

Anonymous authentication is required by Sitefinity. This is due to WCF binding we are currently using. This limitation will be fixed soon. You have to allow anonymous access in IIS. Then go to ~/Sitefinity/Pages and then click on the link “Permissions for all pages” on the left panel. In the new screen click on “Change” button in the “View pages” section. Select the fourth option “Selected roles or users” and then click on “Add roles or users” button. Select the role you want to allow to view your pages.

Regards,
Ivan Dimitrov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 31-May-2011 00:00

Ivan-

I updated my ticket the same, but just want to make sure the forum users are given a clear answer too...

What about this scenario:

http://www.sitefinity.com/documentation/installation-and-administration-guide/system-settings/enabling-windows-authentication.aspx

This scenario involved Windows authentication - so how is it expected to work?

Posted by Community Admin on 01-Jun-2011 00:00

I have tried this example in new web project but when I run my website its still going to login page.


using
System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
  
public partial class Default8 : System.Web.UI.Page
    protected void Page_Load(object sender, EventArgs e)
    
        var membershipProvider = "";
        var userName = "admin";
        var password = "admin@2";
        var rememberMe = true;

blah blahhblah blahhblah blahhblah blahhblah blahh
My requirement is my web site need to talk to sitefinity svc services like "Sitefinity/services/Content/ContentItemService.svc" and get the content and feed to my website.
To call this services I need to be authenticated but its not working. Even when I make client calls thru jquery like this
function WCFJSON()
     
        Type = "GET";
        Url = "http://localhost:49213/Sitefinity/services/Content/ContentItemService.svc/f294027d-268f-40d1-b869-cb93b59f4f95/";
               Data = '';
        ContentType = "application/json; charset=utf-8";
        DataType = "json"; varProcessData = true;
        CallService();
   
I am getting error saying I am not authenticated/session timeout.
I would appreciate if you can give us working example.

Posted by Community Admin on 02-Jun-2011 00:00

Hi kiran,

Currently it is not possible to use our services if you are not authenticated. We know about this extensibility issue and we  have to expose a proper way to authenticate requests through another service or some methods.

Kind regards,
Ivan Dimitrov
the Telerik team

Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

This thread is closed