This post is mostly notes for my self. I spend a few hours trying to get this to work so didn’t want to loose it.
I have a running STS that works perfectly with Passive Federation. I provide a GUI where customers can authenticate them self though various social providers like Facebook and linked in, but they can also login using their own STS (mostly ADFS). I needed to offer this though Active Federation too. (user sends a Issue Request Token with a UserNameWSTrustBinding and I need to validate this against all STS providers I have registered for that username )
There is a billion examples on Google on how to do this but I kept getting HTTP error 404 when calling the web service. but after trying hundred of thousand's different web.config setups I finally managed to get it working.
So I create a class that can validate username and password
Imports Microsoft.IdentityModel.Tokens
Imports Microsoft.IdentityModel.Claims
Imports System.IdentityModel.Tokens
Public Class CustomUserNameSecurityTokenHandler
Inherits UserNameSecurityTokenHandler
Private _CanValidateToken As Boolean = True
Public Overrides ReadOnly Property CanValidateToken() As Boolean
Get
Return _CanValidateToken
End Get
End Property
Public Overrides Function ValidateToken(token As System.IdentityModel.Tokens.SecurityToken) As Microsoft.IdentityModel.Claims.ClaimsIdentityCollection
Dim userNameToken As UserNameSecurityToken = TryCast(token, UserNameSecurityToken)
If userNameToken Is Nothing Then
Throw New ArgumentException("The security token is not a valid username token.")
End If
If userNameToken.UserName = userNameToken.Password Then
Dim identity As IClaimsIdentity = New ClaimsIdentity()
identity.Claims.Add(New Claim(ClaimTypes.Name, userNameToken.UserName))
identity.Claims.Add(New Claim(ClaimTypes.Role, "NoobsAndMorrons"))
Return New ClaimsIdentityCollection(New IClaimsIdentity() {identity})
Else
Throw New InvalidOperationException("Username/password is incorrect in STS.")
End If
Return MyBase.ValidateToken(token)
End Function
End Class
And then I added these sections to my web.config file
First we need to remove Microsoft's default handler and add the above class
<microsoft.identityModel>
<service>
<securityTokenHandlers>
<remove type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add type="CustomUserNameSecurityTokenHandler" />
</securityTokenHandlers>
<service>
<microsoft.identityModel>
Next we add a placeholder for the web service requests. Add an text file and rename it issue.svc, and add this to it.
<%@
ServiceHost
Factory="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory"
Service="CustomSecurityTokenServiceConfiguration"
%>
Next go back to web.config and add this
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract" >
<endpoint address="" binding="customBinding" contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustFeb2005SyncContract"/>
<endpoint address="" binding="customBinding" contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrust13SyncContract"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<federatedServiceHostConfiguration />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<serviceCertificate findValue="7A41CF269D6BCDED80DDD9B6FD517E37891453B5" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding >
<security authenticationMode="UserNameOverTransport" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<system.serviceModel>
Enjoy …I know I didn’t
Ingen kommentarer:
Send en kommentar