Sitefinity 10 with custom OpenID auth provider

Posted by Community Admin on 04-Aug-2018 14:24

Sitefinity 10 with custom OpenID auth provider

All Replies

Posted by Community Admin on 11-Apr-2017 00:00

Hi,

 

Has anyone got SF10 working with a custom OpenID provider yet?

Our company uses IdentityServer4 so I'm trying to integrate that. Support gave me an example, I can create a secure page in the CMS which when hit redirects me to a login page, which has a link to my STS allowing me to login. I have got everything working up to this point, when I return back to Sitefinity after login I just get an Windows Authentication popup, which I cancel to get an error, nothing in the logs except for "Message: Identity Server: UnexpectedError" which isn't much help!

 

Also, Ideally I want to go straight to my STS after hitting the secure page, not the Sitefinity login page, does anyone know how to do that?

Posted by Community Admin on 12-Apr-2017 00:00

Well, this is interesting. I am trying to do the same thing, but I am surprised that you were told by support that a custom class is required.

I am confused why this can't be accomplished by just using Sitefinity settings, as described here. docs.sitefinity.com/administration-configure-single-sign-on-with-sitefinity-cms-as-sts (up to the part where you start adding custom shared membership provider connection strings).

When we try this (against IdentityServer 3's MVC Authentication sample) by putting that site's address into our Sitefinity site as an issuer, adding the RememberMe scope, etc. we get to the point where the redirect to the IdP happens, we can type in credentials, but upon return to the Sitefinity site, we get a message about login failing, and this error message in the authentication log: 

User login failed with exception: Index was outside the bounds of the array.

No popup here.

Posted by Community Admin on 12-Apr-2017 00:00

Hi, the link you posted shows how to setup Sitefinity as an STS, that's not what I want, I already have an STS (IdentityServer4)

Posted by Community Admin on 12-Apr-2017 00:00

Yes, sorry, I was using that document as an example of where in Sitefinity you should be able to set up any IdP, not just another Sitefinity site. We borrowed from the first few steps like this:

Navigate to Administration » Settings » Advanced.
In the left pane, expand Authentication » RelyingParty.
In Issuer, enter the full URL to the STS, concatenated by path to the STS.
I entered localhost:44319/.../ (for IdentityServer3)
In Realm, enter the URL where the STS should redirect back to. 
I entered https://localhost:44370/ (the Sitefinity site)
In Application client name, for each client that you are configuring, enter a unique value.

I entered "sf"

I then created in-memory clients and scopes as needed in the IdentityServer3 project.

 

Posted by Community Admin on 12-Apr-2017 00:00

Ah I see. Interestingly, that seems to solvethe issue in that it redirect straight to my STS. I can't seem to get it to authenticate with IdentityServer4 though, are you using implicit and adding openid, profile and rememberMe scopes?

I suspect you are getting login failed because you're not redirecting back to the correct URL in order to retrieve the token. I think it will also miss creating the User in Sitefinity, which is what setting it up under AuthenticationProviders should do

Posted by Community Admin on 12-Apr-2017 00:00

I tried different redirect URLS and was getting all kinds of errors in the browser.

Here is the scope I added to in memory scopes.  (before this, the authentication log was showing an invalid_scope error message).

                new Scope
               
                    Enabled = true,
                    Name = "rememberMe",
                    Type = ScopeType.Identity,
                    Claims = new List<ScopeClaim>
                   
                        new ScopeClaim("rememberMe")
                   
               

Here is the client added to in memory clients.

 new Client
               
                    ClientName = "Sitefinity Client",
                    ClientId = "sf",
                    Flow = Flows.Implicit,
                    RedirectUris = new List<string>
                   
                        "https://localhost:44370/",
                    ,
                    PostLogoutRedirectUris = new List<string>
                   
                        "https://localhost:44370/"
                    ,
                    AllowedScopes = new List<string>
                   
                        "openid",
                        "profile",
                        "roles",
                        "rememberMe"
                   
               

Here is the in memory user

 new InMemoryUser
               
                    Username = "bob",
                    Password = "secret",
                    Subject = "1",
                    Claims = new[]
                   
                        new Claim(Constants.ClaimTypes.GivenName, "Bob"),
                        new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
                        new Claim(Constants.ClaimTypes.Name, "Bob Smith"),
                        new Claim(Constants.ClaimTypes.Email, "bob@bob.com"),
                        new Claim(Constants.ClaimTypes.ExternalProviderUserId, "bob2@bob.com"),
                        new Claim(Constants.ClaimTypes.PreferredUserName, "bob3@bob.com"),
                        new Claim(Constants.ClaimTypes.Role, "BackendUsers"),
                        new Claim(Constants.ClaimTypes.Role, "Administrators"),
                        new Claim("rememberMe","false"),
                        new Claim("sub","123456")
                   
               

Posted by Community Admin on 12-Apr-2017 00:00

I've turned on Logging for the inbuilt IdentityServer. The error I get using my custom AuthenticationProvider when returning to the CMS from my STS is

Message: Telerik.Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "Telerik.Sitefinity.Security.UserManager", name = "MPS".
Exception occurred while: Calling constructor Telerik.Sitefinity.Security.UserManager(System.String providerName).
Exception is: MissingProviderConfigurationException - There is no configuration for data provider with the name of "MPS" for "Telerik.Sitefinity.Security.UserManager" manager. Please check the spelling of the name and whether such configuration exists.

 

Posted by Community Admin on 12-Apr-2017 00:00

I have this working on IdentityServer4.  You must allow "email" in the scope since Sitefinity now uses that as the unique identifier for each user.  My scope looks like this:

 

AllowedScopes =
                   
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email

                 

 

I had scope problems as well and limited it to just those 3 during testing to minimize any conflicts (actually I haven't been able to expand it yet for more scopes).

 

Also, I personally had problems using https:// for localhost testing.  Maybe you have a legit cert but I think part of my problem was I only have a selfsigned cert on my dev machine.  For testing I ran my identityserver on http.  On production it worked fine switching back to https.

 

 

Posted by Community Admin on 12-Apr-2017 00:00

Can I ask how you turn on logging for the builtin identity server?

 

As for your error message I did not encounter that.  Are you using a custom membership provider named "MPS" ?  I just got my custom membership provider working with this.  I got additional instructions (below) from support to configure.  If you're not using a custom membership provider you can use the same instructions but make sure it's set to "Default" instead of possibly MPS?

************************************

To achieve your desired behavior you need to go Administration -> Settings -> Advanced -> Authentication -> SecurityTokenService -> AuthenticationProviders -> CustomSts (the provider record you have created) and change the Data Provider field to be the name of the custom Membership provider as it is configured under Administration -> Settings -> Advanced -> Security -> MembershipProviders.

This will ensure that the CreateUser methods of the custom provider are called instead of those on the Default provider.

Posted by Community Admin on 13-Apr-2017 00:00

Thanks for the reply.

That was it! My Data Provider was set to MPS, should have been Default. Support omitted that from my instructions! It would have been much simpler if that field was a dropdown listing the Data Provider's rather than free text!

Logging is under Authentication > IdentityServer > Enable Logging

When you enable it and use a custom STS the first warning message says "Message: Using custom redirect URI validator - you are running with scissors." :)

 

Have you worked out how to go straight to your STS rather than the default login page first? I'm going to try using info from the 2nd post above with the ReturnUrl for OpenID. This will override the default login page for Sitefinity so before anyone does it make sure you setup a custom login page that allows you access to the dashboard!

Posted by Community Admin on 13-Apr-2017 00:00

Unfortunately,  setting my STS under RelyingParty doesn't work. I am redirect straight to my STS when I hit a secured CMS page, I can login, but upon returning to /Sitefinity/Authenticate/OpenID/signin-mps I get an error

Message: CORS request made for path: /signin-mps from origin: https://mystswebsite but rejected because invalid CORS path

 

Telerik Support say it is not possible to redirect straight to my STS upon hitting a secure page, we have to go through the login page. This is not a complete solution and is unusable without the ability to do that. 

Posted by Community Admin on 18-Apr-2017 00:00

I've had further clarification from Telerik Support saying that overriding the default STS to your own will not work, here's a copy

The error you are getting can be resolved by configuring your STS to allow CORS for the domain on which Sitefinity is running by adding it to the list of AllowCorsOrigins. Even if that error is resolved, however, the authentication will still not work when the login page is bypassed. In this case, some of the logic that searches for a user in the Sitefinity database and creates one if it doesn't exist is skipped and therefore there will always be an exception.

I am currently discussing this with our developers to see whether there is a possibility of achieving your desired behavior. I will get back to you with more information.

Basically, at the moment Sitefinity 10 is no good if you want it to participate in a Single Sign On type setup with multiple websites. If your customer is already logged in to your STS and clicks a link to a secure CMS page they will be redirected to a Sitefinity login page where they will have to know to ignore the email/password box and know that they should click a button labelled 'OpenIdConnect' !!!??? As if that is going to work :)

I'm really disappointed with Telerik on this, we've been promising people SSO integration based on the Telerik roadmap and now we cannot deliver it, lets hope this can be resolved in a minor release. All we need is someway of setting a single default Authentication Provider.

Posted by Community Admin on 18-Apr-2017 00:00

I'm not sure if I understand your situation fully so this info might not apply to you but maybe my scenario will get you closer?  I'm still having problems getting the ReturnUrl to work (I always return to the homepage) but I'm able to go directly to my IdentiyServer4 login page if a user hits the either a frontend secured page or a backend page.

 

First I setup a custom login page (let's call it /login) by just creating a page and dropping an MVC Login Widget.  I configured that widget to show my external provider as an alternative login option.  Now, I don't actually log in here obviously.  What it does provide is a link via that external button to authenticate off your exteranl provider (we'll call it ExProvider)  which would be /login/LoginExternalProvider/ExProvider .  So if you go to that page directly, it first hits your Sitefinity site, tells sitefinity to start the authentication process and forwards the user to your IdentityServer.

The second step is to tell Sitefinity to use this new page as the default login page.  So go to Administration » Settings » Advanced » Project » DefaultSite and for FrontEndLoginPageUrl put in /login/LoginExternalProvider/ExProvider .  So this works for protected frontend pages but not the backend.

The final step for the backend is to go to Administration » Settings » Advanced » Security and  check AuthenticateOnFrontendLoginPageTitle which tells sitefinity to use your custom login page instead of the default backend page.  Now when you hit a backend page it will redirect to your custom login page, which in turn redirects to your IdentityServer.

 

Like I said the one problem is I'm always redirected to the homepage rather than the original page requests.  I don't know if this is a Sitefinity bug, problem w/ my workaround solution, or an issue with my IdentityServer (though I don't think it's my IdentityServer as ReturnUrl works on other sites properly).

 

I hope this helps!

 

Posted by Community Admin on 18-Apr-2017 00:00

It's probably also worth noting, in my situation I'm not changing the default STS Relay Party.  The custom openid code they provided as far as I know is intended to be used in conjunction with the builtin IdentityServer3.  As you've noted, I don't think you'll get much support from them using your own anytime soon.  For compatibility sake, I'm leaving their own IdentityServer3 in place and let that manage the authentication.  So have it do the forwarding and receiving from to my external IdentityServer rather than have Sitefinity use my IdentityServer directly if that makes sense.

Posted by Community Admin on 19-Apr-2017 00:00

Yeah, changing the default STS in Sitefinity was a false start as it will never create the user in Sitefinity after authenticating with the custom STS. 

If you take a look at the default login page that Sitefinity creates you'll see the link to your custom STS if something like this

sitefinityUrl/.../external

I'm guessing Sitefinity stores the correct page to return to in the database against that Guid.

I was hoping there would be a way to edit the code on the default login page to add some JavaScript to fire the link to the custom STS immediately onload. Unfortunately the /Sitefinity/Authenticate/OpenID/login doesn't seem to be listed under /Sitefinity/Administration/BackendPages

 

Posted by Community Admin on 22-Aug-2017 00:00

Hi ,

I am currently working on the configuration on Sitefinity application with External Authentication based on the posts above and the steps mentioned in the link docs.sitefinity.com/for-developers-configure-custom-external-openid-connect-provider.

For my application, the Identity server application user is authenticated successfully in the external STS application but it redirects me back to the Homepage of my Sitefinity application (which is my login page). Even if I try to access urls of other pages in CMS, the "Redirect URi" doestn't work. 

Can anybody suggest as how can i Modify the "Redirect URi" so that i can get the Sitefinity application redirected to the page i precisely want to ?

Thanks,

Alka

Posted by Community Admin on 22-Aug-2017 00:00

I never got the redirect url to work properly on Sitefinity nor patience to submit a ticket about it (redirect works w/ same config on my Angular2 site).  I did a hackish thing where I set a cookie in OnUnauthorizedAccess event in Global.asax.cs file before the person sent to the identity server then on the homepage, have a little javascript that looks for that cookie and redirects if it exists.  Would love to know also if others got it working properly.

This thread is closed