Skip to content
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

Add Mixed-auth-AllowAnonymous-workaround #34

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
6 changes: 6 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ jobs:
uses: actions/setup-dotnet@v2
with:
dotnet-version: 3.1.x

- name: Setup .NET 6
uses: actions/setup-dotnet@v2
with:
dotnet-version: 6.0.x

- name: Setup .NET 7
uses: actions/setup-dotnet@v2
with:
dotnet-version: 7.0.x

- name: Restore dependencies
run: dotnet restore
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<PackageReference Include="OpenIddict.Client" Version="4.0.0" />
<PackageReference Include="OpenIddict.Client.SystemNetHttp" Version="4.0.0" />
<PackageReference Include="System.ServiceModel.Duplex" Version="4.10.*" />
<PackageReference Include="System.ServiceModel.Federation" Version="4.10.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.10.*" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.10.*" />
<PackageReference Include="System.ServiceModel.Security" Version="4.10.*" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"ExtendedData": {
"inputs": [
"https://localhost:7233/MixedAuthService.svc"
],
"collectionTypes": [
"System.Array",
"System.Collections.Generic.Dictionary`2"
],
"namespaceMappings": [
"*, ServiceReference1"
],
"targetFramework": "net7.0",
"typeReuseMode": "All"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
//------------------------------------------------------------------------------
// <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 ServiceReference1
{


[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.IAnonymousService")]
public interface IAnonymousService
{

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAnonymousService/EchoAnonymous", ReplyAction="http://tempuri.org/IAnonymousService/EchoAnonymousResponse")]
System.Threading.Tasks.Task<string> EchoAnonymousAsync(string value);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
public interface IAnonymousServiceChannel : ServiceReference1.IAnonymousService, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
public partial class AnonymousServiceClient : System.ServiceModel.ClientBase<ServiceReference1.IAnonymousService>, ServiceReference1.IAnonymousService
{

/// <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 AnonymousServiceClient() :
base(AnonymousServiceClient.GetDefaultBinding(), AnonymousServiceClient.GetDefaultEndpointAddress())
{
this.Endpoint.Name = EndpointConfiguration.BasicHttpBinding_IAnonymousService.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

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

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

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

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

public System.Threading.Tasks.Task<string> EchoAnonymousAsync(string value)
{
return base.Channel.EchoAnonymousAsync(value);
}

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.BasicHttpBinding_IAnonymousService))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
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.BasicHttpBinding_IAnonymousService))
{
return new System.ServiceModel.EndpointAddress("https://localhost:7233/MixedAuthService.svc/anonymous");
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}

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

private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
{
return AnonymousServiceClient.GetEndpointAddress(EndpointConfiguration.BasicHttpBinding_IAnonymousService);
}

public enum EndpointConfiguration
{

BasicHttpBinding_IAnonymousService,
}
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.ISecuredService")]
public interface ISecuredService
{

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAnonymousService/EchoAnonymous", ReplyAction="http://tempuri.org/IAnonymousService/EchoAnonymousResponse")]
System.Threading.Tasks.Task<string> EchoAnonymousAsync(string value);

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISecuredService/Echo", ReplyAction="http://tempuri.org/ISecuredService/EchoResponse")]
System.Threading.Tasks.Task<string> EchoAsync(string value);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
public interface ISecuredServiceChannel : ServiceReference1.ISecuredService, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
public partial class SecuredServiceClient : System.ServiceModel.ClientBase<ServiceReference1.ISecuredService>, ServiceReference1.ISecuredService
{

/// <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 SecuredServiceClient() :
base(SecuredServiceClient.GetDefaultBinding(), SecuredServiceClient.GetDefaultEndpointAddress())
{
this.Endpoint.Name = EndpointConfiguration.BasicHttpBinding_ISecuredService.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

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

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

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

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

public System.Threading.Tasks.Task<string> EchoAnonymousAsync(string value)
{
return base.Channel.EchoAnonymousAsync(value);
}

public System.Threading.Tasks.Task<string> EchoAsync(string value)
{
return base.Channel.EchoAsync(value);
}

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.BasicHttpBinding_ISecuredService))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
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.BasicHttpBinding_ISecuredService))
{
return new System.ServiceModel.EndpointAddress("https://localhost:7233/MixedAuthService.svc/authenticated");
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}

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

private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
{
return SecuredServiceClient.GetEndpointAddress(EndpointConfiguration.BasicHttpBinding_ISecuredService);
}

public enum EndpointConfiguration
{

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

using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.Extensions.DependencyInjection;
using OpenIddict.Client;
using ServiceReference1;

// Request an access_token
var services = new ServiceCollection();
services.AddOpenIddict()
.AddClient(options =>
{
options.AllowClientCredentialsFlow();
options.DisableTokenStorage();
options.UseSystemNetHttp();
options.AddRegistration(new OpenIddictClientRegistration
{
Issuer = new Uri("https://localhost:7222/", UriKind.Absolute),
ClientId = "console_app",
ClientSecret = "secret",
Scopes = { "api" }
}
);
});
var provider = services.BuildServiceProvider();
var service = provider.GetRequiredService<OpenIddictClientService>();
var (tokenResponse, _) = await service.AuthenticateWithClientCredentialsAsync(new Uri("https://localhost:7222/", UriKind.Absolute), new [] { "api" });

Console.WriteLine($"Retrieved access_token {tokenResponse.AccessToken}");

// Create an authenticated client and call 'Echo' and 'EchoAnonymous'
var channelFactory = new ChannelFactory<ISecuredServiceChannel>(new BasicHttpBinding(BasicHttpSecurityMode.Transport),
new EndpointAddress("https://localhost:7233/MixedAuthService.svc/authenticated"));
var channel = channelFactory.CreateChannel();

var context = new OperationContext(channel);
using (var _ = new OperationContextScope(context))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = $"Bearer {tokenResponse.AccessToken}";
context.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
var response = await channel.EchoAsync("Hello world");
Console.WriteLine(response);
var response2 = await channel.EchoAnonymousAsync("Hey");
Console.WriteLine(response2);
}

// Create an anonymous client and call 'EchoAnonymous'
var anonymousChannelFactory = new ChannelFactory<IAnonymousServiceChannel>(new BasicHttpBinding(BasicHttpSecurityMode.Transport),
new EndpointAddress("https://localhost:7233/MixedAuthService.svc/anonymous"));

var anonymousChannel = anonymousChannelFactory.CreateChannel();

var response3 = await anonymousChannel.EchoAnonymousAsync("Bonjour");
Console.WriteLine(response3);

Console.ReadLine();

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenIddict.AspNetCore" Version="4.0.0" />
</ItemGroup>
</Project>
Loading