I'm trying to build a system working with ADFS and claims. At the moment, this is just a "toy" implementation.
I've built a very simple MVC web application, set it up using the "Identity and Access..." wizard in Visual Studio to talk to an ADFS 2.0 server, and deployed it to an IIS server. All works fine, and I can examine and list the received claims.
The next step is to build a Web API based REST service (representing back-end services that the MVC application is going to depend on), so I want to pass the credentials across to that back-end server so that it can make suitable authorization decisions.
So the first step is for me to create the delegation token (and I'll then, hopefully, work out what to do with it in terms of the HttpClient
class to make the rest call). I've got this:
//We need to take the bootstrap token and create an appropriate ActAs token
var rst = new RequestSecurityToken
{
AppliesTo = new EndpointReference("https://other-iis.example.com/Rest"),
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Symmetric,
ActAs = new SecurityTokenElement(((BootstrapContext)((ClaimsIdentity)User.Identity).BootstrapContext).SecurityToken)
};
var sts = new SecurityTokenService(); //This line isn't valid
var resp = sts.Issue(System.Threading.Thread.CurrentPrincipal as ClaimsPrincipal, rst);
But, the issue is that SecurityTokenService
is abstract. I can't find any types derived from this class in either System.IdentityModel
nor System.IdentityModel.Services
, and the above doesn't include any reference to the ADFS server which I'll obviously need to provide at some point.
Of course, I may be going down completely the wrong route also, or am just hitting a minor stumbling block and not seeing a much larger one looming in the distance, so any advice on that would be appreciated also.
I've looked at, for example, Identity Delegation Scenario, but that uses CreateChannelActingAs
, which I don't think is going to work when I'm talking to a rest service (or will it?), and also doesn't seem to apply to .NET 4.5.
Delegation tokens at the client-side Requesting new Delegation Tokens from the server. A renewer can be specified when requesting the token. Renewing Delegation Tokens (if the client specifies itself as the 'renewer'), or ask another party (the specified 'renewer') to renew Delegation Tokens.
Delegation tokens are a secret key shared with the HDFS NameNode that can be used to impersonate a user for job execution. While these tokens can be renewed, new tokens can be obtained only by clients authenticating to the NameNode using Kerberos credentials. By default, delegation tokens are valid for a day.
Delegation tokens are security tokens that are issued to a delegate to act as a user. AD FS returns a delegation token with claims about the client, targeted for the Web service. The Web application uses the token that was obtained from AD FS in step 3 to access the Web service that is acting as the client.
I am requesting tokens from an ADFS 2.0 for caching and looking at the DisplayToken. Maybe this can help you get started.
Here is what I can up with:
public SecurityToken GetToken(out RequestSecurityTokenResponse rstr)
{
Console.WriteLine("Connecting to STS...");
WSTrustChannelFactory factory = null;
try
{
if (_useCredentials)
{
// use a UserName Trust Binding for username authentication
factory =
new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
"https://<adfs>/adfs/services/trust/13/UsernameMixed");
factory.TrustVersion = TrustVersion.WSTrust13;
// Username and Password here...
factory.Credentials.UserName.UserName = "username";
factory.Credentials.UserName.Password = "password";
}
else
{
// Windows authentication over transport security
factory = new WSTrustChannelFactory(
new WindowsWSTrustBinding(SecurityMode.Transport),
"https://<adfs>/adfs/services/trust/13/windowstransport") { TrustVersion = TrustVersion.WSTrust13 };
}
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = SvcEndpoint,
KeyType = KeyTypes.Symmetric,
RequestDisplayToken = true
};
Console.WriteLine("Creating channel for STS...");
IWSTrustChannelContract channel = factory.CreateChannel();
Console.WriteLine("Requesting token from " + StsEndpoint.Uri);
SecurityToken token = channel.Issue(rst, out rstr);
Console.WriteLine("Received token from " + StsEndpoint.Uri);
return token;
}
finally
{
if (factory != null)
{
try
{
factory.Close();
}
catch (CommunicationObjectFaultedException)
{
factory.Abort();
}
}
}
}
You might have to acivate the UsernameMixed Endpoint in your ADFS 2.0 if you want to use it and don't forget to restart the service afterwards!
From msdn
To create an STS you must derive from the SecurityTokenService class. In your custom class you must, at a minimum, override the GetScope and GetOutputClaimsIdentity methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With