Obtain token in JWT format from a custom Sts - wif

I have implemented a custom STS and it works good with Saml token.
Now I need to obtain the token in JWT format, because I need to pass it later to WCF Rest based service.
I've installed the Jwt Token Handler from:
https://nuget.org/packages/System.IdentityModel.Tokens.Jwt/
This is a part of the Web.config in the Sts project:
<securityTokenHandlers name="ActAs">
<clear/>
<add type="System.IdentityModel.Tokens.JwtSecurityTokenHandler, System.IdentityModel.Tokens.Jwt"/>
<!--<add type="System.IdentityModel.Tokens.SamlSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add type="System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />-->
<securityTokenHandlerConfiguration>
<audienceUris>
<add value="URL_RP_STS"/>
<add value="URL_CLIENT"/>
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089">
<trustedIssuers>
<add thumbprint="..." name="StsCustom" />
</trustedIssuers>
</issuerNameRegistry>
</securityTokenHandlerConfiguration>
</securityTokenHandlers>
<audienceUris>
<add value="URL_RP_STS" />
</audienceUris>
<!--certificationValidationMode set to "None" by the the Identity and Access Tool for Visual Studio. For development purposes.-->
<certificateValidation certificateValidationMode="None" />
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="StsCustom">
<keys>
<add thumbprint="..." />
</keys>
<validIssuers>
<add name="StsCustom" />
</validIssuers>
</authority>
</issuerNameRegistry>
</identityConfiguration>
But the Sts continue to generate a SamlSecurityToken.
Is necessary some other configuration to set a specific token type? Is not suffice adding the Jwt token handler in the securityTokenHandlers section?
Thanks

How do you request the token? In WS-Trust you can pass in the token type in the RST. For WS-Federation you need to write code in the STS for that.

Related

microsoft.identityModel migrate to system.Identity model

My current STS configuration from the web is as follows,
<microsoft.identityModel>
<service saveBootstrapTokens="true">
<audienceUris mode="Never"/>
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true" issuer="https://fs.mysite.net/adfs/ls" realm="https://myweb.cloudapp.net/" reply="https://myweb.cloudapp.net/Account/FederatedResult" requireHttps="false"/>
<cookieHandler requireSsl="false"/>
</federatedAuthentication>
<serviceCertificate>
<certificateReference x509FindType="FindBySubjectName" findValue="*.mydomain.net"/>
</serviceCertificate>
<applicationService>
<claimTypeRequired>
<claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true"/>
<claimType type="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true"/>
<claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" optional="true"/>
</claimTypeRequired>
</applicationService>
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<add thumbprint="a5069c80a92e7a49937bba9bc25a85a57b4bbc74" name="https://fs.myweb.net/adfs/services/trust"/>
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="None"/>
</service>
I need to introduce MachineKeySessionSecurityTokenHandler as below, (in the web farm environment I need to enforce cookie encryption by mahcinekey)
<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>
But tag is not available in system.identityModel. Also federatedAuthentication tag gives errors. Can someone help me to migrate microsoft.identityModel to system.identityModel version.
Did you put the following at the top of your web.config ?
<configuration>
<configSections>
<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" />

Redirecting Users from Unauthorized Page

I have an MVC application that I recently converted the authentication/authorization method from forms to federated. Everything works fine, but on the home page I have to create a cookie for the authorization of the rest of my site to work properly. When users navigate to the home page first it works great, if they navigate to a different page first where authorization is required they get a 401 unauthorized error page.
When I had the forms authentication implemented it would redirect users that were unauthorized to the login page, with federation I no longer have a login page so I would like to redirect to the home page. With forms authentication the redirection was automatic, how would I setup something similar for my federated application?
Here are the federated portions of my web.config that are relevant. Again, federated authentication/authorization works, just the unauthorized redirect that isn't.
<system.web>
<customErrors mode="Off"/>
<authentication mode="None"/>
<authorization>
<deny users="?"/>
</authorization>
<membership defaultProvider="ADMembershipProvider">
<providers>
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionProtection="Secure" attributeMapUsername="sAMAccountName" connectionStringName="ADConn" connectionUsername="UName" connectionPassword="Pass" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="ActiveDirectoryRoleProvider" cacheRolesInCookie="true" cookieName=".ADLibraryROLES" cookiePath="/" cookieTimeout="1440" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="true" cookieProtection="All">
<providers>
<clear />
<add name="ActiveDirectoryRoleProvider" connectionStringName="ADConn" connectionUsername="UName" connectionPassword="Pass" attributeMapUsername="sAMAccountName" type="MyApp.ActiveDirectoryRoleProvider" />
</providers>
</roleManager>
</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="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>
<audienceUris>
<add value="https://fed.example.com/"/>
</audienceUris>
<securityTokenHandlers>
<add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</securityTokenHandlers>
<certificateValidation certificateValidationMode="None"/>
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="http://myfedservice.example.com/adfs/services/trust">
<keys>
<add thumbprint="mythumb"/>
</keys>
<validIssuers>
<add name="http://fed.example.com/adfs/services/trust"/>
</validIssuers>
</authority>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="true"/>
<wsFederation passiveRedirectEnabled="true" issuer="https://fed.example.com/adfs/ls/" realm="https://fed.example.com/" reply="https://fed.example.com/" requireHttps="true" persistentCookiesOnPassiveRedirects="true"/>
</federationConfiguration>
</system.identityModel.services>
You can configure this in the wsFederation section, see MSDN for further details. By setting the “passiveRedirectEnabled” to true, the WSFederationAuthenticationModule will look at all outgoing responses, trying to find HTTP 401s. If it finds a 401, it will modify the response and turn it into a redirect to the STS. Please note that in production you want to change requireHttps to true.
<system.identityModel.services>
<federationConfiguration>
<wsFederation passiveRedirectEnabled="true"
issuer="http://localhost:15839/wsFederationSTS/Issue"
realm="http://localhost:50969/" reply="http://localhost:50969/"
requireHttps="false"
signOutReply="http://localhost:50969/SignedOutPage.html"
signOutQueryString="Param1=value2&Param2=value2"
persistentCookiesOnPassiveRedirects="true" />
<cookieHandler requireSsl="false" />
</federationConfiguration>
Please note that you also need to add these modules:
<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="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>
and the following config sections:
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<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" />

UserManager and organizational accounts - cannot connect to the database ( mvc 5)

Got the following problem:
I've created simple mvc 5 project with individual user accounts authentication.
Everything works i can add users,roles,everything is stored in the database - all seems to be fine. Now i want to change authetication to organisational:
<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="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>
<audienceUris>
<add value="myUrl" />
</audienceUris>
<securityTokenHandlers>
<remove type="System.IdentityModel.Tokens.SamlSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<add type="System.IdentityModel.Tokens.SamlSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<samlSecurityTokenRequirement>
<nameClaimType value="myClaim"/>
</samlSecurityTokenRequirement>
</add>
</securityTokenHandlers>
<certificateValidation certificateValidationMode="None" />
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="mySts">
<keys>
<add thumbprint="myThumb" />
</keys>
<validIssuers>
<add name="mySts" />
</validIssuers>
</authority>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="true" />
<wsFederation passiveRedirectEnabled="true" issuer="mySTs" realm="myUrl" requireHttps="true" />
</federationConfiguration>
</system.identityModel.services>
It works - i can authenticate,but when i want to add new user (based on User.Identity.Name to my existing database:
UserManager.CreateAsync(user);
I get weird error:
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. Cannot create an automatic instance. See the Windows Application event log for error details.)
although i didn't change anything in connection,dbcontext and so on.
What could be a reason of such behavior?
Something seems to be missed in your web.config file. Try to add connectionStrings to your web.config by editing the code below according to your database and connection properties:
web.config:
<configuration>
<add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0;
Initial Catalog=aspnet-YourDatabaseName; Integrated Security=SSPI; AttachDBFilename=|DataDirectory|\aspnet-YourDatabaseName.mdf" />

Cookies Set but not Sent in Subsequent Requests

I'm preparing a demo of MembershipReboot for my local user group. I'm experiencing a strange scenario whereby the 2 cookies:
FedAuth; and
FedAuth1
are being set in the headers of the Response. However, in subsequent Requests, they are not part of the headers. I confirmed this using Fiddler and it explains why User.Identity.IsAuthenticated is always false after successful logins.
Is the anything which may be leading to this weird scenario?
Cheers
I had a few subtle errors in my Web.config file.
In the configSections element
Instead of:
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
I had:
<section name="system.identitymodel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
In the system.webServer > modules element
Instead of:
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler"/>
I had:
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
For the system.identityModel.services element
Instead of:
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" persistentSessionLifetime="30:00:00"/>
</federationConfiguration>
</system.identityModel.services>
I had:
<system.identitymodel.services>
<federationconfiguration>
<cookiehandler requiressl="false" persistentSessionLifetime="30:00:00" />
</federationconfiguration>
</system.identitymodel.services>
This was tough to diagnose, so always be careful when configuring your application!
MembershipReboot rocks!!!

Implementing ASP.NET web with WIF & ADFS 1.0

I have developed a solution with ASP.NET front-end using WCF-services as back-end. The web-site currently authenticates using ADFS 1.0 (I do not have any control of the ADFS-implementation but it has been configured for my web-application). Also, it's no option to upgrade to ADFS 2.0 (at least not in the near future)
The configuration in Web.config for this is the following:
<httpModules>
<add name="Identity Federation Services Application Authentication Module" type="System.Web.Security.SingleSignOn.WebSsoAuthenticationModule, System.Web.Security.SingleSignOn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" />
</httpModules>
<membership defaultProvider="SingleSignOnMembershipProvider2">
<providers>
<add name="SingleSignOnMembershipProvider2" type="System.Web.Security.SingleSignOn.SingleSignOnMembershipProvider2, System.Web.Security.SingleSignOn.PartialTrust, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" fs="https://urltoadfs/adfs/fs/FederationServerService.asmx" />
</providers>
</membership>
<websso>
<authenticationrequired />
<urls>
<returnurl>https://myapplication/</returnurl>
</urls>
<fs>https://urltoadfs/adfs/fs/FederationServerService.asmx</fs>
<isSharePoint />
</websso>
This works fine and i can access the application using an account in ADFS. The problem is that I need to convert this claim-identity to a WindowsIdentity to access the back-end WCF services (they use Windows Authentication with impersonation/delegation).
Is there any way to accomplish this with ADFS 1.0? I have tried to use WIF (Windows Identity Foundation) but I cannot find any clear information if it's possible to use it together with ADFS 1.0 as STS. I have also investigated the "Windows NT token-based applications"-option (http://technet.microsoft.com/en-us/library/cc784956(v=ws.10).aspx) but I would like to avoid changes in the current ADFS-implementation if possible.
To test the WIF-option I used the following configuration in Web.config (the part on websso removed):
<httpModules>
<add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ClaimsAuthorizationModule" type="Microsoft.IdentityModel.Web.ClaimsAuthorizationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>
<microsoft.identityModel>
<service>
<audienceUris>
<add value="https://myapplication/" />
</audienceUris>
<applicationService>
<claimTypeRequired>
<claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" optional="true" />
</claimTypeRequired>
</applicationService>
<securityTokenHandlers>
<add type="Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<samlSecurityTokenRequirement mapToWindows="true" useWindowsTokenService="true" />
</add>
</securityTokenHandlers>
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true"
issuer="https://urltoadfs/adfs/fs/FederationServerService.asmx"
realm="https://myapplication/"
requireHttps="true" />
</federatedAuthentication>
</service>
</microsoft.identityModel>
I also have the "Claims to Windows Token Service" (c2WTS) running on the web-server.
I get redirected to the ADFS-server but I just receives a general error from the server.

Resources