How to have an instance of CoreWCF.Channels.TransportBindingElement? - wcf

I have a legacy code written by .NET 4.7.2 which should be upgraded to netstandard2.0. Here is the legacy code:
TransportBindingElement bindingElement = new HttpsTransportBindingElement
{
RequireClientCertificate = true,
AllowCookies = false,
AuthenticationScheme = AuthenticationSchemes.Anonymous,
BypassProxyOnLocal = false,
DecompressionEnabled = true,
ExtendedProtectionPolicy = new ExtendedProtectionPolicy(
PolicyEnforcement.Always,
ProtectionScenario.TransportSelected,
null),
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
KeepAliveEnabled = true,
ManualAddressing = false,
MaxBufferPoolSize = MaxBufferPoolSize,
MaxBufferSize = MaxBufferSize,
MaxReceivedMessageSize = MaxReceivedMessageSize,
MaxPendingAccepts = 0,
ProxyAuthenticationScheme = AuthenticationSchemes.Anonymous,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true
};
Since the TransportBindingElement class is an abstract and HttpsTransportBindingElement is not defined in CoreWCF, the question is: what is the alternative solution for the above code to migrate to netstandard2.0 using CoreWCF?

Related

Is There Any Way to use a custom generator with nswag on the command line?

We are using NSwag to generate web clients.
We have some custom generators for TypeName and OperationName.
Currently we use the NSwag class library and have custom code written to call in a console application.
Here is our CSharpClientGeneratorSettings. As you can see we have a custom class for TypeNameGenerator and OperationNameGenerator.
var cSharpClientGeneratorSettings = new CSharpClientGeneratorSettings
{
ClassName = "{controller}Client",
CSharpGeneratorSettings =
{
Namespace = this._clientNamespace,
ClassStyle = CSharpClassStyle.Inpc,
DateTimeType = "System.DateTime",
DateType = "System.DataTime",
TypeNameGenerator = new CustomTypeNameGenerator(),
JsonLibrary = CSharpJsonLibrary.SystemTextJson
},
GenerateClientInterfaces = true,
GenerateClientClasses = true,
OperationNameGenerator = new TClientGenerator(),
ExceptionClass = "YadaYada.Library.Client.SwaggerException",
InjectHttpClient = true,
SerializeTypeInformation = true,
DisposeHttpClient = true,
WrapDtoExceptions = false,
GenerateOptionalParameters = true,
ExposeJsonSerializerSettings = false,
ParameterArrayType = "System.Collections.Generic.IList",
ResponseArrayType = "System.Collections.Generic.IList",
GenerateExceptionClasses = false,
UseBaseUrl = false,
GenerateDtoTypes = false,
AdditionalNamespaceUsages = this._additionalNamespaces
};
I would like to run this code generation as an MSBuild task without have to build and deploy our console application. Is there any way to 'inject' our custom name operators into the command line version of NSwag? (nswag.exe)?

Could not establish secure channel for SSL/TLS with authority in .net 5

I am getting this error only with the application developed in .net 5.0,. For .net 4.5* application it is working fine.
With .net 5.0 console application when calling WCF service getting SSl/TLS issue. Already tried below code but not working:
ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertficate;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = true;
I have written this lines in Main function before creating the host:
Host.CreateDefaultBuilder(args)
Complete error is as below:
Could not establish trust relationship for the SSL/TLS secure channel with authority
Binding Used for WCF call is as below:
var binding = new BasicHttpsBinding
{
CloseTimeout = new TimeSpan(0, 1, 0),
OpenTimeout = new TimeSpan(0, 1, 0),
ReceiveTimeout = new TimeSpan(0, 1, 0),
SendTimeout = new TimeSpan(0, 1, 0),
MaxBufferPoolSize = 2147483647,
MaxBufferSize = 2147483647,
MaxReceivedMessageSize = 2147483647,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true,
AllowCookies = false,
MessageEncoding = WSMessageEncoding.Mtom,
Name = "dlBinding",
BypassProxyOnLocal = false,
Security =
{
Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
Transport = new HttpTransportSecurity
{
ClientCredentialType = HttpClientCredentialType.Certificate,
ProxyCredentialType = HttpProxyCredentialType.Basic,
}
}
};

Inserting image corrupts Open XML SDK generated Word file

I have tried to adapt the code in https://learn.microsoft.com/en-us/office/open-xml/how-to-insert-a-picture-into-a-word-processing-document to insert an image to a table cell in my .Net Core MVC app. However, inserting the image just corrupts the word file.
I have noticed that when I extract the corrupt docx file, the "media" folder is outside the "word" folder. However, when I manually add an image to a docx file, the "media" folder is present inside the "word" folder.
...code here...
ImagePart imagePart = wordDoc.MainDocumentPart.AddImagePart(ImagePartType.Jpeg);
using (FileStream stream = new FileStream(#$"{_env.WebRootPath}\images\mono.jpg", FileMode.Open))
{
imagePart.FeedData(stream);
}
var element = new Drawing( new DW.Inline( new DW.Extent() { Cx = 990000L, Cy = 792000L },
new DW.EffectExtent(){ LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
new DW.DocProperties(){ Id = (UInt32Value)11U, Name = "Picture 1" },
new DW.NonVisualGraphicFrameDrawingProperties( new A.GraphicFrameLocks() { NoChangeAspect = true }),
new A.Graphic( new A.GraphicData( new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties(){ Id = (UInt32Value)10U, Name = "New Bitmap Image.jpg" },
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(new A.BlipExtensionList(new A.BlipExtension(){ Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" })) { Embed = wordDoc.MainDocumentPart.GetIdOfPart(imagePart), CompressionState = A.BlipCompressionValues.Print, },
new A.Stretch(new A.FillRectangle())),
new PIC.ShapeProperties( new A.Transform2D(
new A.Offset() { X = 0L, Y = 0L },
new A.Extents() { Cx = 990000L, Cy = 792000L }),
new A.PresetGeometry(new A.AdjustValueList()){ Preset = A.ShapeTypeValues.Rectangle }))){ Uri = "https://schemas.openxmlformats.org/drawingml/2006/picture" })) { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U, EditId = "50D07946" });
Table table0 = new Table();
TableProperties props0 = new TableProperties(...code here...);
table0.AppendChild<TableProperties>(props0);
var tr0 = new TableRow();
var tc0 = new TableCell();
var pp0 = new ParagraphProperties(new SpacingBetweenLines() { After = "0" }, new Justification() { Val = JustificationValues.Center });
var rn0 = new Run(element);
var pg0 = new Paragraph(pp0, rn0);
tc0.Append(new TableCellProperties(new TableCellWidth { Type = TableWidthUnitValues.Dxa, Width = "1792" })), new HorizontalMerge { Val = MergedCellValues.Restart });
tc0.Append(pg0);
tr0.Append(tc0);
table0.Append(tr0);
body.Append(table0);
doc.Append(body);
...code here...
I have figured it out. The MSDN docs are to blame.
This line in the MSDN docs:
) { Uri = "https://schemas.openxmlformats.org/drawingml/2006/picture" })
is invalid, because of the https that should be http.
Changing that makes the document open without issue.

Question for RawRabbit: sends various messages autonomously

I didn't understand, I have a client that sends various messages autonomously, it doesn't wait for the ack but it has to send them and that's it, but seems that it send only the first one and all the others only when I close the application.
where am I wrong? what should i set?.
var config = new RawRabbitConfiguration()
{
Username = username,
Password = password,
VirtualHost = "/",
Hostnames = new List<string>() { hostname },
AutoCloseConnection = false,
//Ssl = new SslOption() { Enabled = true },
Port = port,
Exchange = new GeneralExchangeConfiguration
{
AutoDelete = false,
Durable = true,
Type = RawRabbit.Configuration.Exchange.ExchangeType.Direct
},
Queue = new GeneralQueueConfiguration
{
Exclusive = false,
AutoDelete = false,
Durable = true
}
};
var options = new RawRabbitOptions() { ClientConfiguration = config };
client = RawRabbitFactory.CreateSingleton(options);
client.SubscribeAsync<MessageModel>(async msg =>
{
return await Task.Run(() => MessageReceived(msg));
},
ctx => ctx.UseSubscribeConfiguration(
cfg => cfg.FromDeclaredQueue(
queue => queue.WithName(queueName))))
.GetAwaiter();
UPDATE: function for sending that I use...
public void SendMessage(MessageModel message, string machineName = null, string exchangeName = null)
{
if (!string.IsNullOrEmpty(machineName))
message.MachineName = machineName;
else if (string.IsNullOrEmpty(message.MachineName))
message.MachineName = this.MachineName;
if (!string.IsNullOrEmpty(LastMessageReceived?.ID))
message.RequestID = LastMessageReceived.ID;
else
message.RequestID = string.Empty;
if (!string.IsNullOrEmpty(LastMessageReceived?.MachineName))
message.MachineNameDest = LastMessageReceived.MachineName;
else if (string.IsNullOrEmpty(message.MachineNameDest))
message.MachineNameDest = string.Empty;
try
{
if (string.IsNullOrEmpty(exchangeName))
client.PublishAsync<MessageModel>(message);
else
client.PublishAsync<MessageModel>(message,
ctx => ctx.UsePublishConfiguration(
cfg => cfg.OnExchange(exchangeName)));
}
catch (Exception ex)
{
OnError?.Invoke(this, ex);
}
LastMessageReceived = null;
}
EDIT:
In what case is the error "Stage Initialized has no additional middlewares registered" generated ?
I cannot understand why this error is generated on "SubscribeAsync" and after does not send messages. :(
Please, help me.

IdentityServer4 client - Refreshing access tokens on CookieAuthenticationEvents

I am trying to use refresh token when the access token expires. A similar so question is answered here. And a sample code to renew token by an action
And i end up with the following code in the startup.cs
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
//ExpireTimeSpan = TimeSpan.FromSeconds(100),
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async x =>
{
if (x.Properties?.Items[".Token.expires_at"] == null) return;
var logger = loggerFactory.CreateLogger(this.GetType());
var now = DateTimeOffset.UtcNow;
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = tokenExpireTime.Subtract(now.DateTime);
if (timeElapsed > timeRemaining)
{
var httpContextAuthentication = x.HttpContext.Authentication;//Donot use the HttpContext.Authentication to retrieve anything, this cause recursive call to this event
var oldAccessToken = await httpContextAuthentication.GetTokenAsync("access_token");
var oldRefreshToken = await httpContextAuthentication.GetTokenAsync("refresh_token");
logger.LogInformation($"Refresh token :{oldRefreshToken}, old access token:{oldAccessToken}");
var disco = await DiscoveryClient.GetAsync(AuthorityServer);
if (disco.IsError) throw new Exception(disco.Error);
var tokenClient = new TokenClient(disco.TokenEndpoint, ApplicationId, "secret");
var tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken);
logger.LogInformation("Refresh token requested. " + tokenResult.ErrorDescription);
if (!tokenResult.IsError)
{
var oldIdToken = await httpContextAuthentication.GetTokenAsync("id_token");
var newAccessToken = tokenResult.AccessToken;
var newRefreshToken = tokenResult.RefreshToken;
var tokens = new List<AuthenticationToken>
{
new AuthenticationToken {Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken}
};
var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });
var info = await httpContextAuthentication.GetAuthenticateInfoAsync("Cookies");
info.Properties.StoreTokens(tokens);
await httpContextAuthentication.SignInAsync("Cookies", info.Principal, info.Properties);
}
x.ShouldRenew = true;
}
else
{
logger.LogInformation("Not expired");
}
}
}
});
The client setup is as follows
AllowAccessTokensViaBrowser = true,
RefreshTokenUsage = TokenUsage.ReUse,
RefreshTokenExpiration = TokenExpiration.Sliding,
AbsoluteRefreshTokenLifetime = 86400,
AccessTokenLifetime = 10,
AllowOfflineAccess = true,
AccessTokenType = AccessTokenType.Reference
After successfully login, i am getting a 401 for every other request. And the log says
[Identity Server]2017-07-04 10:15:58.819 +01:00 [Debug]
"TjpIkvHQi../cfivu6Nql5ADJJlZRuoJV1QI=" found in database: True
[Identity Server]2017-07-04 10:15:58.820 +01:00 [Debug]
"reference_token" grant with value:
"..9e64c1235c6675fcef617914911846fecd72f7b372" found in store, but has
expired.
[Identity Server]2017-07-04 10:15:58.821 +01:00 [Error] Invalid
reference token. "{ \"ValidateLifetime\": true,
\"AccessTokenType\": \"Reference\", \"TokenHandle\":
\"..9e64c1235c6675fcef617914911846fecd72f7b372\" }"
[Identity Server]2017-07-04 10:15:58.822 +01:00 [Debug] Token is
invalid.
[Identity Server]2017-07-04 10:15:58.822 +01:00 [Debug] Creating
introspection response for inactive token.
[Identity Server]2017-07-04 10:15:58.822 +01:00 [Information] Success
token introspection. Token status: "inactive", for API name: "api1"
Any help would by highly appreciated
UPDATE:
Basically, when the token expires i get a System.StackOverflowException on the following line
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
UPDATE 2:
Do not use HttpContext.Authentication to retrieve anything. Check my answer below to find the working implementaion
I was working on this for last two days and could not make this work. Funnily, after posting the question here, within 2 hours I make it working :)
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async x =>
{
if (x.Properties?.Items[".Token.expires_at"] == null) return;
var now = DateTimeOffset.UtcNow;
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = tokenExpireTime.Subtract(now.DateTime);
WriteMessage($"{timeRemaining} and elapsed at {timeElapsed}");
if (timeElapsed > timeRemaining)
{
var oldAccessToken = x.Properties.Items[".Token.access_token"];
var oldRefreshToken = x.Properties.Items[".Token.refresh_token"];
WriteMessage($"Refresh token :{oldRefreshToken}, old access token {oldAccessToken}");
var disco = await DiscoveryClient.GetAsync(AuthorityServer);
if (disco.IsError) throw new Exception(disco.Error);
var tokenClient = new TokenClient(disco.TokenEndpoint, ApplicationId, "secret");
var tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken);
if (!tokenResult.IsError)
{
var oldIdToken = x.Properties.Items[".Token.id_token"];//tokenResult.IdentityToken
var newAccessToken = tokenResult.AccessToken;
var newRefreshToken = tokenResult.RefreshToken;
var tokens = new List<AuthenticationToken>
{
new AuthenticationToken {Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken}
};
var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });
x.Properties.StoreTokens(tokens);
WriteMessage($"oldAccessToken: {oldAccessToken}{Environment.NewLine} and new access token {newAccessToken}");
}
x.ShouldRenew = true;
}
}
}
Basically httpContextAuthentication.GetTokenAsync make this recursive, for that reason StackOverflowException occured.
Please let me know if this implementation has any issue