Claims based auth with non sitefinity Security Token Service
Can anyone help me please.
I have a simple security token issuer (the project template from Microsoft ASPNetSTSWebApp) I have websites that successfully use this for their authentication. (For reference I have added the config from the working ASP.Net web App as I can't upload the whole solution)
I am trying to now get a brand new Sitefinity site to use this as its issuer. I have added a secure page (requires Administrator role) and have added a new user SFUser and added them to the administrators role (and backend user).
I have altered the SF site web.config to try and make it similar to my working example and I get a redirection to my to my STS but it has dropped the necessary action parameters. I have tried altering the advanced settings too, but am not totally clear I have done this bit correctly. I (and I am sure lot's of others) could really use some kind of walkthrough on getting this last bit working. The documentation doesn't really help me (http://www.sitefinity.com/documentation/documentationarticles/setting-up-sso-with-claims-based-authentication ) this tells you how to do it with another sitefinity sight, but I have not had success with my external STS.
Has anyone had success integrating with an external claims issuer?
OK so I have been pointed at this document which I had seen and tried on my own STS site with no success, I am falling down at the second hurdle trying to do it with Teleriks example STS:
http://www.sitefinity.com/documentation/documentationarticles/setting-up-sso-with-windows-authentication
"Extract the files from SitefinityStsWebApp.zip to the created folder.
SitefinityStsWebApp.zip contains the SitefinityStsWebApp web application that you can use for the STS site and is located in your Sitefinity account."
Where can I download SitefinityStsWebApp.zip I have download the 991 MB SDK spent ages installing it - and cannot find it. Neither Google or Teleriks search shows where it is and I cannot find it as a standalone download in my account area?
Can anyone help please?
For anyone who might run into the same issues
To get the SitefinityStsWebApp.zip go to Your Account -> Download and Manage your products -> Download Installer And Other Resources (for Sitefinity) -> Browse all product files. There is a list of downloadable items: the msi installer, the project manager and at the bottom - SitefinityStsWebApp.zip.
As for the issue I am having
"Sitefinity does not implement the WS protocol and wa=wsignin1.0 is not passed. Every request to the STS is to be treated as a Sign In request except when sign_out=true is set."
Hopefully that should be enough to get me going, and hopefully it'll save others some time.
Also note when adding the user to your sitefintiy site in this example do not specify a domain:
My windows authentication identity in STS site was domain\\username
In sitefinity
This worked: username (no domain)
These did not
username@domain.local
domain\username
domain\\username
Once you got it working were you still able to publish pages? I get errors on publish like I have posted here:
www.sitefinity.com/.../external-security-token-service-issues.aspx
I have now got an STS working that uses our existing forms Db I thought I'd share in case it saved others some time (If you notice any errors please let me know and I'll edit the post - I am doing this from memory and have played with sitefinity alot to get it working so can't rule out getting confused).
My requirements are:
Use existing forms based database
Use Custom role provider as we already have mechanisms in place to manage roles
Only Sign in once to have filtered content in Sitefnity, but to also use our backend websites.
All websites have been done in IIS7.5 on Windows 7(64bit) using Sitefnity 5.0.2860.0 .
I have downloaded the example Sts website and created a website for it (http://stsinternal.company.local)
I have created a Sitefnity website (http://SFPoc.company.local)
1. Modify the Sts website so that the authentication is forms based and uses our existing db.
I amended the SimpleWebTokenHandler.cs slightly
//var winPrincipal = context.User as WindowsPrincipal;
//if (winPrincipal == null || !winPrincipal.Identity.IsAuthenticated)
// throw new ConfigurationException("This web site is not correctly configured for Windows authentication.");
//
//
//var principal = ClaimsPrincipal.CreateFromPrincipal(winPrincipal);
var principal = ClaimsPrincipal.CreateFromPrincipal(context.User);
2. In Sitefinity modify the security.config
<
securityTokenIssuers
>
<
add
key
=
"SOMEKEY"
encoding
=
"Hexadecimal"
membershipProvider
=
"AspNetSqlMembershipProvider"
realm
=
"http://localhost"
/>
<
add
key
=
"SOMEKEY"
encoding
=
"Hexadecimal"
membershipProvider
=
"AspNetSqlMembershipProvider"
realm
=
"http://SFPoc.company.local/Sitefinity/Authenticate/SWT"
/>
<
add
key
=
"SOMEKEY"
encoding
=
"Hexadecimal"
membershipProvider
=
"AspNetSqlMembershipProvider"
realm
=
"http://stsinternal.company.local/swt.ashx"
/>
</
securityTokenIssuers
>
<
relyingParties
>
<
add
key
=
"SOMEKEY"
encoding
=
"Hexadecimal"
realm
=
"http://localhost"
/>
<
add
key
=
"SOMEKEY"
encoding
=
"Hexadecimal"
realm
=
"http://SFPoc.Company.local"
/>
</
relyingParties
>
Add this within the root node:
<
membershipProviders
>
<
add
type
=
"System.Web.Security.SqlMembershipProvider"
enabled
=
"True"
name
=
"AspNetSqlMembershipProvider"
/>
</
membershipProviders
>
If you wish to use custom roles from this example you will need to add this too (in the root node):
<
roleProviders
>
<
add
type
=
"SitefinityWebApp.CompanyRoleDataProvider"
enabled
=
"True"
name
=
"CompanyRoleDataProvider"
/>
</
roleProviders
>
3. In Sitefinity modify the web.config
<
connectionStrings
>
<
add
name
=
"ApplicationServices"
connectionString
=
"your connection string"
/>
</
connectionStrings
>
<
system.web
>
<!--<membership defaultProvider="Default">-->
<
membership
defaultProvider
=
"AspNetSqlMembershipProvider"
>
<
providers
>
<
clear
/>
<
add
name
=
"Default"
type
=
"Telerik.Sitefinity.Security.Data.SitefinityMembershipProvider, Telerik.Sitefinity"
/>
<
add
name
=
"AspNetSqlMembershipProvider"
type
=
"System.Web.Security.SqlMembershipProvider"
connectionStringName
=
"ApplicationServices"
enablePasswordRetrieval
=
"false"
enablePasswordReset
=
"true"
requiresQuestionAndAnswer
=
"false"
requiresUniqueEmail
=
"true"
maxInvalidPasswordAttempts
=
"5"
minRequiredPasswordLength
=
"6"
minRequiredNonalphanumericCharacters
=
"0"
passwordAttemptWindow
=
"10"
applicationName
=
"/"
/>
</
providers
>
</
membership
>
</
system.web
>
and edit the microsoft.identitymodel area to point at your Sts
<
microsoft.identityModel
>
<
service
>
<
claimsAuthenticationManager
type
=
"Telerik.Sitefinity.Security.Claims.SFClaimsAuthenticationManager, Telerik.Sitefinity"
/>
<
securityTokenHandlers
>
<
add
type
=
"Telerik.Sitefinity.Security.Claims.SWT.SWTSecurityTokenHandler, Telerik.Sitefinity"
/>
</
securityTokenHandlers
>
<
audienceUris
mode
=
"Never"
/>
<
federatedAuthentication
>
<
wsFederation
passiveRedirectEnabled
=
"true"
issuer
=
"http://stsinternal.company.local/swt.ashx"
realm
=
"http://SFPoc.company.local"
requireHttps
=
"false"
/>
<
cookieHandler
requireSsl
=
"false"
/>
</
federatedAuthentication
>
<
issuerNameRegistry
type
=
"Telerik.Sitefinity.Security.Claims.CustomIssuerNameRegistry, Telerik.Sitefinity"
>
<
trustedIssuers
/>
</
issuerNameRegistry
>
<
issuerTokenResolver
type
=
"Telerik.Sitefinity.Security.Claims.SWT.WrapIssuerTokenResolver, Telerik.Sitefinity"
/>
</
service
>
</
microsoft.identityModel
>
I believe that was all that was needed to implement a forms based STS, you can use your power user and grant the forms users roles there is another tab in the user screen with the name AspNetSqlMembershipProvider this contains your membership users.
If you wish to implement the custom role provider, there were various properties that needed setting before it would work, the posts I found always seemed to have something missing, but I eventually got it working by using the code below:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
Telerik.Sitefinity.Model;
using
Telerik.Sitefinity.Security;
using
Telerik.Sitefinity.Security.Data;
using
Telerik.Sitefinity.Security.Model;
namespace
SitefinityWebApp
public
class
CompanyRoleDataProvider : RoleDataProvider
private
List<Role> _roles;
private
List<UserLink> _userLinks;
public
CompanyRoleDataProvider()
var role0 =
new
Role Id = Guid.Parse(
"C18AFA58-8F53-41EA-8F70-7F604CECF090"
), Name =
"testSubsrciption 0"
, ApplicationName =
base
.ApplicationName, LastModified = DateTime.MinValue;
var role1 =
new
Role Id = Guid.Parse(
"C18AFA58-8F53-41EA-8F70-7F604CECF091"
), Name =
"testSubsrciption 1"
, ApplicationName =
base
.ApplicationName, LastModified = DateTime.MinValue ;
var role2 =
new
Role Id = Guid.Parse(
"C18AFA58-8F53-41EA-8F70-7F604CECF092"
), Name =
"testSubsrciption 2"
, ApplicationName =
base
.ApplicationName, LastModified = DateTime.MinValue ;
_roles =
new
List<Role>
role0,
role1,
role2
;
var link1 = NewUserLink(Guid.NewGuid());
// Username is from membership database userId
link1.UserId = Guid.Parse(
"B97D099D-A98F-42E6-9CB5-1300342DA23D"
);
link1.Role = role0;
var link2 = NewUserLink(Guid.NewGuid());
// Username is from membership database userId
link2.UserId = Guid.Parse(
"DB8BC7D6-3F06-4A7B-B068-558DE5E3DFE6"
);
link2.Role = role1;
_userLinks =
new
List<UserLink>
link1,
link2,
;
public
override
Role CreateRole(
string
roleName)
throw
new
NotImplementedException();
public
override
Role CreateRole(Guid id,
string
roleName)
throw
new
NotImplementedException();
public
override
Role GetRole(Guid id)
return
_roles.Where(items => items.Id == id).FirstOrDefault();
public
override
IQueryable<Role> GetRoles()
return
_roles.AsQueryable();
public
override
void
Delete(Role item)
throw
new
NotImplementedException();
public
override
UserLink CreateUserLink()
return
NewUserLink();
private
UserLink NewUserLink(Guid id)
var link = CreateUserLink();
link.UserId = id;
return
link;
private
UserLink NewUserLink()
var link =
new
UserLink ApplicationName =
base
.ApplicationName;
var mi =
new
ManagerInfo();
mi.ApplicationName = link.ApplicationName;
mi.ManagerType =
typeof
(UserManager).FullName;
mi.ProviderName =
"AspNetSqlMembershipProvider"
;
link.MembershipManagerInfo = mi;
return
link;
public
override
UserLink CreateUserLink(Guid id)
return
NewUserLink(id);
public
override
UserLink GetUserLink(Guid id)
return
_userLinks.Where(item => item.Id == id).FirstOrDefault();
public
override
IQueryable<UserLink> GetUserLinks()
return
_userLinks.AsQueryable();
public
override
void
Delete(UserLink item)
throw
new
NotImplementedException();
None of this is best practice, it is a bare bones STS using an existing membership database. The role provider needs a lot more work but has allowed me to prove my point.
Since I got this working I have merged my StstWebsite with an empty on from the Windows Identity Sts Web Application Project, so my other backend sites can use this new WS-Protocol handler for their authentication, as you have logged into the STS website it can serve either WS or SWT and only require authenticating the user once - Single Sign On!
Hope this helps someone
Dave Scuffle
I did a blog post today and which might help some of you. I intend to blog about few advance scenarios as well in coming weeks.
zamd.net/.../
For anyone who still needs a useful non-Sitefinity STS, I've forked IdentityServer to be compatible with Sitefinity. You can check out the source on GitHub here, and my blog post about here.
Hi David,
How did you get this working for a non sitefinity asp.net app?
Hello. Has anybody tried David's steps (See below, 29 Jun 2012 Link to this post) lately? I am trying to get my SF app to talk to an external STS (it's the SF STS web app) but I'm getting an endless redirect loop between the SF app and the STS.