Skip to content

Conversation

@AigioL
Copy link

@AigioL AigioL commented Nov 18, 2025

improve #968

Comment on lines 35 to 38
/// <summary>
/// The internal identifier for Alipay users will no longer be independently available going forward and will be replaced by OpenID.
/// </summary>
public const string UserId = "urn:alipay:user_id";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On reflection, if this is going to be deprecated, it would be better not to expose it as a public member. Otherwise it feels like we're adding a new API that's immediately obsolete.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserId cannot be modified to private because applications created before OpenId or legacy code still require it. For newly created applications, OpenId should be used unless a support ticket is submitted to request the platform to enable legacy UserId. I have updated the code and added the ObsoleteAttribute.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a new public API that is immediately obsolete serves no useful purpose to the user and adds maintenance burden for us to remove it in the future (which is then itself a breaking change).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intention was to delete the property entirely, not just to remove the [Obsolete] attribute.

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Extension methods to configure Sign in with Alipay authentication capabilities for an HTTP application pipeline.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually called "Sign in with Alipay", or is this just copy-paste where "Apple" has been changed to "Alipay"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's called "Sign In Alipay", not "Sign In with Alipay"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be “Sign in with Alipay” because, like Apple, it uses a third-party platform account for login. This will redirect you to an Alipay webpage displaying a QR code. Use the Alipay mobile app to scan the code and log in.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Sign In with Apple" is the name of the product (docs), "Sign in with Apple" is the description of what the user does.

"Sign In Alipay" appears to be the name, as it is not grammatically correct English to be a description of what the user is doing.


Span<byte> hash = stackalloc byte[MD5.HashSizeInBytes];
#pragma warning disable CA5351
MD5.HashData(bytes, hash);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value should be checked.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MD5 algorithm has a fixed length, so there is no need to check the returned result. If the input array is too short, it will throw an exception.

/// </summary>
private const int StackallocByteThreshold = 256;

private static string CalculateMd5(ReadOnlySpan<char> chars)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still overcomplicated really. This isn't a hot path.

The whole thing could just be:

var buffer = Encoding.UTF8.GetBytes(chars);
return MD5.HashData(buffer);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have balanced high performance with code conciseness. The return value here should be a lowercase hex string. The updated code uses stackalloc instead of byte[] to avoid fragmented memory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically yes, but I don't think it's of importance here against a simpler implementation.

Copy link
Author

@AigioL AigioL Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest submission has been simplified.

private static string CalculateMd5(string s)
{
var buffer = Encoding.UTF8.GetBytes(s);
Span<byte> hash = stackalloc byte[MD5.HashSizeInBytes];
#pragma warning disable CA5351
MD5.HashData(buffer, hash);
#pragma warning restore CA5351
return Convert.ToHexStringLower(hash);
}

@martincostello
Copy link
Member

Please don't resolve comments where no code changes have been made - otherwise it makes things harder to review as I have to uncollapse the comments in the UI, and if I disagree I just have to unresolve them anyway.

Comment on lines 33 to 35
#pragma warning disable CS0618
ClaimActions.MapJsonKey(Claims.UserId, "user_id");
#pragma warning restore CS0618
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's going to be obsolete, just hard-code the value here without the need for the constant. Then we can just delete it in the future without having to also change the public API surface.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public Func<string, CancellationToken, Task<ReadOnlyMemory<char>>>? PublicKey { get; set; }

/// <inheritdoc />
public override void Validate()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this also validate that PublicKey is not null?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aicodeguard

This comment has been minimized.

AigioL and others added 3 commits January 17, 2026 10:39
- Removed the [Obsolete] marker from AlipayAuthenticationConstants.UserId while retaining explanatory comments.
- ClaimActions now directly maps “urn:alipay:user_id” to “user_id” and removes the obsolete mapping for Claims.UserId.
- Added non-null validation for PublicKey in certificate mode.
… certificate resolution

This submission simplifies Alipay certificate signing configurations by directly passing the certificate serial number (SN) string. It removes the ApplicationCertificateSnKeyId, RootCertificateSnKeyId, and PublicKey delegate properties, with corresponding methods adjusted to directly read the SN. The certificate SN calculation utility class and extension methods for reading public keys via files have been eliminated. This removes the complexity of dynamic certificate resolution, enhancing configuration intuitiveness and usability.
@AigioL
Copy link
Author

AigioL commented Jan 21, 2026

Based on aicodeguard's comment, there is indeed no need to parse the PEM certificate file with every request. I removed the certificate-related content and simplified all changes by using fixed configuration values.

fe4159d

Comment on lines 35 to 38
/// <summary>
/// The internal identifier for Alipay users will no longer be independently available going forward and will be replaced by OpenID.
/// </summary>
public const string UserId = "urn:alipay:user_id";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intention was to delete the property entirely, not just to remove the [Obsolete] attribute.

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Extension methods to configure Sign in with Alipay authentication capabilities for an HTTP application pipeline.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Sign In with Apple" is the name of the product (docs), "Sign in with Apple" is the description of what the user does.

"Sign In Alipay" appears to be the name, as it is not grammatically correct English to be a description of what the user is doing.

Comment on lines +51 to +52
ArgumentNullException.ThrowIfNull(Options.ApplicationCertificateSn);
ArgumentNullException.ThrowIfNull(Options.RootCertificateSn);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't arguments to the method. They were already validated in the options. If they are subsequently messed with by the integrator that's user error.

Suggested change
ArgumentNullException.ThrowIfNull(Options.ApplicationCertificateSn);
ArgumentNullException.ThrowIfNull(Options.RootCertificateSn);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants