Skip to content

Add Security Token Provider Sample #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Extensibility/Security/TokenProvider/Client/Client.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Using Include="CoreWcf.Samples.TokenProvider" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.ServiceModel.Http" Version="6.0.0-rc.23205.4" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"ExtendedData": {
"inputs": [
"https://localhost:5001/CalculatorService?wsdl"
],
"collectionTypes": [
"System.Array",
"System.Collections.Generic.Dictionary`2"
],
"namespaceMappings": [
"*, CoreWcf.Samples.TokenProvider"
],
"sync": true,
"targetFramework": "net6.0",
"typeReuseMode": "All"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace CoreWcf.Samples.TokenProvider
{


[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://CoreWcf.Samples.TokenProvider", ConfigurationName="CoreWcf.Samples.TokenProvider.ICalculatorService")]
public interface ICalculatorService
{

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Add", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/AddResponse")]
double Add(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Add", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/AddResponse")]
System.Threading.Tasks.Task<double> AddAsync(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Subtract", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/SubtractResponse")]
double Subtract(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Subtract", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/SubtractResponse")]
System.Threading.Tasks.Task<double> SubtractAsync(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Multiply", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/MultiplyResponse")]
double Multiply(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Multiply", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/MultiplyResponse")]
System.Threading.Tasks.Task<double> MultiplyAsync(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Divide", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/DivideResponse")]
double Divide(double n1, double n2);

[System.ServiceModel.OperationContractAttribute(Action="http://CoreWcf.Samples.TokenProvider/ICalculatorService/Divide", ReplyAction="http://CoreWcf.Samples.TokenProvider/ICalculatorService/DivideResponse")]
System.Threading.Tasks.Task<double> DivideAsync(double n1, double n2);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
public interface ICalculatorServiceChannel : CoreWcf.Samples.TokenProvider.ICalculatorService, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<CoreWcf.Samples.TokenProvider.ICalculatorService>, CoreWcf.Samples.TokenProvider.ICalculatorService
{

/// <summary>
/// Implement this partial method to configure the service endpoint.
/// </summary>
/// <param name="serviceEndpoint">The endpoint to configure</param>
/// <param name="clientCredentials">The client credentials</param>
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);

public CalculatorServiceClient() :
base(CalculatorServiceClient.GetDefaultBinding(), CalculatorServiceClient.GetDefaultEndpointAddress())
{
this.Endpoint.Name = EndpointConfiguration.WSHttpBinding_ICalculatorService.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public CalculatorServiceClient(EndpointConfiguration endpointConfiguration) :
base(CalculatorServiceClient.GetBindingForEndpoint(endpointConfiguration), CalculatorServiceClient.GetEndpointAddress(endpointConfiguration))
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public CalculatorServiceClient(EndpointConfiguration endpointConfiguration, string remoteAddress) :
base(CalculatorServiceClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public CalculatorServiceClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) :
base(CalculatorServiceClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public double Add(double n1, double n2)
{
return base.Channel.Add(n1, n2);
}

public System.Threading.Tasks.Task<double> AddAsync(double n1, double n2)
{
return base.Channel.AddAsync(n1, n2);
}

public double Subtract(double n1, double n2)
{
return base.Channel.Subtract(n1, n2);
}

public System.Threading.Tasks.Task<double> SubtractAsync(double n1, double n2)
{
return base.Channel.SubtractAsync(n1, n2);
}

public double Multiply(double n1, double n2)
{
return base.Channel.Multiply(n1, n2);
}

public System.Threading.Tasks.Task<double> MultiplyAsync(double n1, double n2)
{
return base.Channel.MultiplyAsync(n1, n2);
}

public double Divide(double n1, double n2)
{
return base.Channel.Divide(n1, n2);
}

public System.Threading.Tasks.Task<double> DivideAsync(double n1, double n2)
{
return base.Channel.DivideAsync(n1, n2);
}

public virtual System.Threading.Tasks.Task OpenAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
}

private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WSHttpBinding_ICalculatorService))
{
System.ServiceModel.WSHttpBinding result = new System.ServiceModel.WSHttpBinding();
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Mode = System.ServiceModel.SecurityMode.TransportWithMessageCredential;
result.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.None;
result.Security.Message.ClientCredentialType = System.ServiceModel.MessageCredentialType.UserName;
return result;
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}

private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WSHttpBinding_ICalculatorService))
{
return new System.ServiceModel.EndpointAddress("https://localhost:5001/CalculatorService");
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}

private static System.ServiceModel.Channels.Binding GetDefaultBinding()
{
return CalculatorServiceClient.GetBindingForEndpoint(EndpointConfiguration.WSHttpBinding_ICalculatorService);
}

private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
{
return CalculatorServiceClient.GetEndpointAddress(EndpointConfiguration.WSHttpBinding_ICalculatorService);
}

public enum EndpointConfiguration
{

WSHttpBinding_ICalculatorService,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IdentityModel.Selectors;
using System.ServiceModel.Description;

namespace CoreWcf.Samples.TokenProvider
{
public class MyUserNameClientCredentials : ClientCredentials
{
public MyUserNameClientCredentials()
: base()
{
}

protected override ClientCredentials CloneCore()
{
return new MyUserNameClientCredentials();
}

public override SecurityTokenManager CreateSecurityTokenManager()
{
// return custom security token manager
return new MyUserNameSecurityTokenManager(this);
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IdentityModel.Selectors;
using System.ServiceModel;

namespace CoreWcf.Samples.TokenProvider
{
public class MyUserNameSecurityTokenManager : ClientCredentialsSecurityTokenManager
{
MyUserNameClientCredentials myUserNameClientCredentials;
private readonly string _userNameTokenType = "http://schemas.microsoft.com/ws/2006/05/identitymodel/tokens/UserName";

public MyUserNameSecurityTokenManager(MyUserNameClientCredentials myUserNameClientCredentials)
: base(myUserNameClientCredentials)
{
this.myUserNameClientCredentials = myUserNameClientCredentials;
}

public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
{
// if token requirement matches username token return custom username token provider
// otherwise use base implementation
if (tokenRequirement.TokenType == _userNameTokenType)
{
return new MyUserNameTokenProvider();
}
else
{
return base.CreateSecurityTokenProvider(tokenRequirement);
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace CoreWcf.Samples.TokenProvider
{
class MyUserNameTokenProvider : SecurityTokenProvider
{
static string GetUserName()
{
Console.WriteLine("Username authentication required.");
Console.WriteLine(" Enter username:");
string username = Console.ReadLine();
return username;
}

static string GetPassword()
{
Console.WriteLine("Enter password:");
string password = "";
ConsoleKeyInfo info = Console.ReadKey(true);
while (info.Key != ConsoleKey.Enter)
{
if (info.Key != ConsoleKey.Backspace)
{
password += info.KeyChar;
info = Console.ReadKey(true);
}
else if (info.Key == ConsoleKey.Backspace)
{
if (password != "")
{
password = password.Substring(0, password.Length - 1);

}
info = Console.ReadKey(true);
}
}

for (int i = 0; i < password.Length; i++)
Console.Write("*");

Console.WriteLine();

return password;
}

protected override Task<SecurityToken> GetTokenCoreAsync(TimeSpan timeout)
{
// obtain username and password from the user using console window
string username = GetUserName();
string password = GetPassword();
Console.WriteLine("username: {0}", username);

// return UserNameSecurityToken containing information obtained from user
return Task.FromResult<SecurityToken>(new UserNameSecurityToken(username, password));
}

protected override SecurityToken GetTokenCore(TimeSpan timeout)
{
// obtain username and password from the user using console window
string username = GetUserName();
string password = GetPassword();
Console.WriteLine("username: {0}", username);

// return UserNameSecurityToken containing information obtained from user
return new UserNameSecurityToken(username, password);
}
}
}

Loading