ADFS SSO SAML Windows Integrated Authentication Does Not Work

We are currently working on a single sign-on project through ADFS using the SAML token.
The basic rule that this project should follow:
1. The agent logs into Windows using its credentials.
2. The agent enters the web application (relying party)
3. The web application must redirect to STS in ADFS (Active Directory is an identity provider) and log in using the credentials that the agent used in its Windows authentication (seamless authentication).
4. Therefore, the STS login page should not be displayed , and the user should be authenticated
. 5. After that, you need to get a complaint and a security token so that we can authorize the agent.

Actual result:
1. The redirect is performed for the first time, and re-authentication is required (IE authentication page and Firefox \ Chrome authentication page).
enter image description here
enter image description here

  1. It can authenticate with all kinds of domain users, and not just with an authenticated Windows user.
  2. After the first login to the sts login page, authentication is again not required. However, we do not want a second authentication. Only when logging into Windows (true only for IE).

Customized Environment:
1. Domain controller + ADFS 3.0 server on one computer (Win2k12R2)
2. Web Application Machines (Win2k12 + IIS8.5)
3. Cars are in the same domain

ADFS Configuration:

enter image description here
enter image description here
enter image description here

Relying Party Configuration:

enter image description here enter image description here
enter image description here

IE configuration:
enter image description here
enter image description here
enter image description here

Web Application Configuration:
Authentication:

enter image description here ASP.Net Project:
Web configuration file:

<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> </configSections> <connectionStrings> <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-TestApp-20150730141753;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-TestApp-20150730141753.mdf" /> </connectionStrings> <location path="FederationMetadata"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <system.web> <authorization> <deny users="?" /> </authorization> <authentication mode="None" /> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <pages> <namespaces> <add namespace="System.Web.Optimization" /> </namespaces> <controls><add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" /></controls></pages> <!--<authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880" defaultUrl="~/" /> </authentication>--> <profile defaultProvider="DefaultProfileProvider"> <providers> <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" /> </providers> </profile> <membership defaultProvider="DefaultMembershipProvider"> <providers> <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> </providers> </membership> <roleManager defaultProvider="DefaultRoleProvider"> <providers> <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" /> </providers> </roleManager> <!-- If you are deploying to a cloud environment that has multiple web server instances, you should change session state mode from "InProc" to "Custom". In addition, change the connection string named "DefaultConnection" to connect to an instance of SQL Server (including SQL Azure and SQL Compact) instead of to SQL Server Express. --> <sessionState mode="InProc" customProvider="DefaultSessionProvider"> <providers> <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" /> </providers> </sessionState> </system.web> <system.webServer> <modules> <!--<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />--> <add name="FixedWSFederationAuthenticationModule" type="TestApp.FixedWSFederationAuthenticationModule, TestApp" preCondition="managedHandler" /> <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> </modules> </system.webServer> <system.identityModel> <identityConfiguration saveBootstrapContext="true"> <!-- The identity configuration. No name means default configuration which is always used for passive federation scenarios. see federationConfiguration element --> <audienceUris> <add value="https://ccsp12.pj12.loc/testapp" /> </audienceUris> <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <trustedIssuers> <add thumbprint="91992FCF8B03FF9BD98A259FE93B92620E9DD89A" name="http://sts.pj12.loc/adfs/services/trust" /> </trustedIssuers> </issuerNameRegistry> <certificateValidation certificateValidationMode="None" /> </identityConfiguration> </system.identityModel> <system.identityModel.services> <federationConfiguration> <!-- Configures the WSFederationAuthenticationModule (WSFAM) and the SessionAuthenticationModule (SAM) when using federated authentication through the WS-Federation protocol --> <cookieHandler requireSsl="false" /> <!-- passiveRedirectEnabled true means that a relaying party (test app) instead of having its own login page, it will redirect to the sts issuer for authentication and the sts will reply to the relaying party --> <!-- Due to WSFederationAuthenticationModule bug, the relaying party address must be with '/' at the end --> <wsFederation passiveRedirectEnabled="true" issuer="https://sts.pj12.loc/adfs/ls/" realm="https://ccsp12.pj12.loc/testapp/" reply="https://ccsp12.pj12.loc/testapp/" requireHttps="true" /> </federationConfiguration> </system.identityModel.services> <!--<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" /> <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.1.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" /> <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.1.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>--> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> </entityFramework> </configuration> 

C # code:

 namespace TestApp { public partial class _Default : Page { protected void Page_Load(object sender, EventArgs e) { // local variables string claimsTypes = string.Empty; string claimsValues = string.Empty; string claimsValueTypes = string.Empty; string claimsSubjectNames = string.Empty; string claimsIssuers = string.Empty; // initialize claims and identity ClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal; ClaimsIdentity claimsIdentity = Thread.CurrentPrincipal.Identity as ClaimsIdentity; BootstrapContext bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext; if (claimsPrincipal != null) { signedIn.Text = "You are signed in."; foreach (Claim claim in claimsPrincipal.Claims) { claimsTypes = string.Concat(claimsTypes, "; ", claim.Type); claimsValues = string.Concat(claimsValues, "; ", claim.Value); claimsValueTypes = string.Concat(claimsValueTypes, "; ", claim.ValueType); claimsSubjectNames = string.Concat(claimsSubjectNames, "; ", claim.Subject.Name); claimsIssuers = string.Concat(claimsIssuers, "; ", claim.Issuer); } //claims principals claimType.Text = claimsTypes; claimValue.Text = claimsValues; claimValueType.Text = claimsValueTypes; claimSubjectName.Text = claimsSubjectNames; claimIssuer.Text = claimsIssuers; // ClaimsIdentity isUserAuthenticated.Text = claimsIdentity.IsAuthenticated.ToString(); authenticationType.Text = claimsIdentity.AuthenticationType; claimName.Text = claimsIdentity.Name; // Token // known bug : http://stackoverflow.com/questions/13514553/wif-4-5-bootstrapcontext-security-token-null SecurityToken token = null; if (bootstrapContext.SecurityToken != null) { token = bootstrapContext.SecurityToken; } else if (!bootstrapContext.Token.Equals(string.Empty)) { var handlers = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers; token = handlers.ReadToken(new XmlTextReader(new StringReader(bootstrapContext.Token))); } SamlSecurityToken sst = token as SamlSecurityToken; tokenId.Text = sst.Id; tokenAssertionId.Text = sst.Assertion.AssertionId; tokenIssuer.Text = sst.Assertion.Issuer; } else { signedIn.Text = "You are not signed in."; } } } 
+8
source share
1 answer

Finally, I was able to achieve seamless windows with integrated SSO!

I found some ADFS property called "WIASupportedUserAgents". This means: Supported browsers allowed for WIA (Windows Integrated Authentication).
Doing the following in PowerShell:

 Set-ADFSProperties -WIASupportedUserAgents @("MSIE 6.0", "MSIE 7.0", "MSIE 8.0", "MSIE 9.0", "MSIE 10.0", "MSIE 11.0", "Trident/7.0", "MSIPC", "Windows Rights Management Client", "Mozilla/5.0") 

Instead of restarting the ADFS service.

After setting this property to support all browsers, the SSO system with full authentication started working!
Now I do not get the credentials window, and an authenticated Windows user is automatically authenticated through ADFS.

It works like a charm.

Thanks to everyone and especially Wiktor Zychla for his great desire to help!

+11
source

All Articles