Skip to content

Commit 9d44528

Browse files
committed
Merge branch 'dev' into pr/22792
2 parents 40bd4b2 + 9ff41aa commit 9d44528

File tree

198 files changed

+1899
-410
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

198 files changed

+1899
-410
lines changed

.github/workflows/angular.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ jobs:
2727
with:
2828
fetch-depth: 0
2929

30-
- uses: actions/cache@v2
30+
- uses: actions/cache@v4
3131
with:
3232
path: 'npm/ng-packs/node_modules'
3333
key: ${{ runner.os }}-${{ hashFiles('npm/ng-packs/yarn.lock') }}
3434

35-
- uses: actions/cache@v2
35+
- uses: actions/cache@v4
3636
with:
3737
path: 'templates/app/angular/node_modules'
3838
key: ${{ runner.os }}-${{ hashFiles('templates/app/angular/yarn.lock') }}

Directory.Packages.props

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
<PackageVersion Include="BunnyCDN.Net.Storage" Version="1.0.4" />
1919
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.1" />
2020
<PackageVersion Include="Azure.Storage.Blobs" Version="12.22.1" />
21-
<PackageVersion Include="Blazorise" Version="1.7.3" />
22-
<PackageVersion Include="Blazorise.Components" Version="1.7.3" />
23-
<PackageVersion Include="Blazorise.DataGrid" Version="1.7.3" />
24-
<PackageVersion Include="Blazorise.Snackbar" Version="1.7.3" />
21+
<PackageVersion Include="Blazorise" Version="1.7.6" />
22+
<PackageVersion Include="Blazorise.Components" Version="1.7.6" />
23+
<PackageVersion Include="Blazorise.DataGrid" Version="1.7.6" />
24+
<PackageVersion Include="Blazorise.Snackbar" Version="1.7.6" />
2525
<PackageVersion Include="Castle.Core" Version="5.1.1" />
2626
<PackageVersion Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
2727
<PackageVersion Include="CommonMark.NET" Version="0.15.1" />
@@ -119,7 +119,7 @@
119119
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="8.6.0" />
120120
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.6.0" />
121121
<PackageVersion Include="Minio" Version="6.0.3" />
122-
<PackageVersion Include="MongoDB.Driver" Version="3.1.0" />
122+
<PackageVersion Include="MongoDB.Driver" Version="3.3.0" />
123123
<PackageVersion Include="NEST" Version="7.17.5" />
124124
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
125125
<PackageVersion Include="Nito.AsyncEx.Context" Version="5.1.2" />

abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,10 +693,30 @@
693693
"Permission:BlockUserPolicy": "User Block Policy",
694694
"ManageImages" : "Manage Image",
695695
"ModuleMainImage": "Module Main Image",
696-
"ModuleImageInfo1": "Accepted file types : <strong> JPEG, JPG, PNG </strong>",
696+
"ModuleImageInfo1": "Accepted file types : <strong> JPEG, JPG, PNG, SVG </strong>",
697697
"ModuleImageInfo2": "Max file size : <strong> 1 MB </strong>",
698698
"ModuleImageInfo3": "Image Proportion : <strong> 1:1 </strong>",
699699
"ModuleImageInfo4": "<a href='/images/example-module-img.png' download> Download a sample cover image </a>",
700-
"AreYouSureToDeleteImage": "Are you sure you want to delete this image?"
700+
"AreYouSureToDeleteImage": "Are you sure you want to delete this image?",
701+
"CompactPercentage": "Compact Percentage",
702+
"CompactPercentageDescription": "Percentage of cache entries to remove during compaction (1-100)",
703+
"Settings": "Settings",
704+
"MaxSizeOfInMemoryCache": "Max Size Of In Memory Cache",
705+
"MaxSizeOfInMemoryCacheInfo": "Gets or sets the maximum size of the memory cache.",
706+
"SizeOfTriggerAutoCompact": "Size Of Trigger Auto Compact",
707+
"SizeOfTriggerAutoCompactInfo": "Gets or sets the size threshold that triggers auto-compaction. When the cache size exceeds this value, auto-compaction will be performed",
708+
"AutoCompactPercentage": "Auto Compact Percentage",
709+
"AutoCompactPercentageInfo": "Gets or sets the percentage of items to remove when auto-compaction is triggered (1-100)",
710+
"ClearCaches": "This clears all NuGet content cache",
711+
"CacheLatestVersions": "Cache Latest Versions",
712+
"VersionCount": "Version Count",
713+
"VersionCountInfo": "Gets or sets the number of versions to cache",
714+
"IncludeLeptonX": "Include LeptonX",
715+
"IncludeLeptonXInfo": "Gets or sets whether to include LeptonX in the cache",
716+
"IncludePrerelease": "Include Prerelease",
717+
"IncludePrereleaseInfo": "Gets or sets whether to include prerelease versions in the cache",
718+
"CacheVersionCount": "Cache Version Count",
719+
"CacheVersionCountInfo": "Gets or sets the number of versions to cache",
720+
"CacheLatestVersionsInfo": "This caches the latest versions of the NuGet packages"
701721
}
702722
}

abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@
18881888
"FaqIyzicoPaymentIssuesExplanation7": "Alternatively, you can send the license amount directly via bank wire transfer. For our bank account details, please visit: <a href='https://volosoft.com/bank-account'>Bank Account Information</a> (use USD currency).",
18891889
"FaqIyzicoPaymentIssuesExplanation8": "ABP website doesn't save or process your credit card. We use payment gateways for this and the entire transaction is handled by payment gateways. We have no authority to interfere with the payment process or fix the payment steps. If you have further questions or need additional support, feel free to contact us at <a href='https://abp.io/contact'>abp.io/contact</a>.",
18901890
"BiographyContainsUrlValidationMessage": "Biography cannot contain URL.",
1891-
"CreatePostSEOTitleInfo": "The SEO Title is what appears in search engine results as the clickable headline. By default, it matches the article’s title, but you can customize it here for better search visibility. Keep it clear, compelling, and include target keywords—ideally near the beginning. Aim for around 60 characters to avoid truncation in search results.",
1891+
"CreatePostSEOTitleInfo": "SEO URL is a clean, readable, keyword-rich URL that helps both users and search engines understand what this post is about. Keep it short with 60 characters. SEO titles over 60 characters will be truncated. Use hyphens (-) to separate words (not underscores). Include target keywords near the start. Lowercase only. No stop words unless needed (e.g: \"and\", \"or\", \"the\").",
18921892
"SEOTitle": "SEO Title"
18931893
}
18941894
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Common Errors in JWT Bearer Authentication
2+
3+
When implementing JWT Bearer authentication in an ABP(tiered) application, you might occasionally encounter errors starting with `IDX`. These errors are related to JWT Bearer Token validation and this article will help you understand and resolve them.
4+
5+
## Enable JWT Bearer authentication
6+
7+
Your API project usually contains the following code, which enables JWT Bearer authentication and makes it as the default authentication scheme.
8+
9+
We simply configure the JWT's `Authority` and `Audience` properties, and it will work fine.
10+
11+
```csharp
12+
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
13+
.AddJwtBearer(options =>
14+
{
15+
options.Authority = "https://localhost:44301/"; //configuration["AuthServer:Authority"];
16+
options.Audience = "MyProjectName";
17+
});
18+
```
19+
20+
> `AddJwtBearer` and `AddAbpJwtBearer` will do the same thing, but `AddAbpJwtBearer` is recommended.
21+
22+
## JWT authentication process
23+
24+
Let's take a look at how the above code works.
25+
26+
A JWT Token usually consists of three parts: `Header`, `Payload`, and `Signature`.
27+
28+
- `Header`: Contains the type and signing algorithm of the token
29+
- `Payload`: Contains the claims of the token, including `sub`, `aud`, `exp`, `iat`, `iss`, `jti`, `preferred_username`, `given_name`, `role`, `email`, etc.
30+
- `Signature`: The cryptographic signature of the token used to verify its authenticity
31+
32+
Here is an example of a JWT Token issued by `AuthServer(OpenIddict)`:
33+
34+
The `Header` part:
35+
36+
![JWT Header](header.png)
37+
38+
The `Payload` part:
39+
40+
![JWT Payload](payload.png)
41+
42+
### TokenValidationParameters
43+
44+
In the `JwtBearerOptions`, there is a `TokenValidationParameters` property, which is used to validate the JWT Token.
45+
46+
The default implementation for JWT Token validation is `JsonWebTokenHandler`, which comes from the [Microsoft.IdentityModel.JsonWebTokens](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/) package.
47+
48+
We didn't set the `TokenValidationParameters` property in the code above, so the default values below will be used:
49+
50+
```csharp
51+
//...
52+
TokenValidationParameters.ValidateAudience = true
53+
TokenValidationParameters.ValidAudience = "MyProjectName"
54+
TokenValidationParameters.ValidAudiences = null
55+
56+
TokenValidationParameters.ValidateIssuer = true
57+
TokenValidationParameters.ValidIssuer = null
58+
TokenValidationParameters.ValidIssuers = null
59+
//...
60+
```
61+
62+
### JWT Bearer Token Validation Process
63+
64+
During JWT Bearer authentication, API website will get the token from the HTTP request and validate it.
65+
66+
The `JsonWebTokenHandler` will get the `OpenID Connect` metadata from the `AuthServer`, it will be used in the validation process, the current metadata request address is: https://localhost:44301/.well-known/openid-configuration , it is a fixed address calculated from the `Authority` property.
67+
68+
First, the token's Signature is verified using the public key obtained from `OpenID Connect` metadata(https://localhost:44301/.well-known/jwks).
69+
70+
Then, the payload is validated. The payload is a JSON object containing essential information such as the `token type`, `expiration time`, `issuer`, and `audience` etc.
71+
72+
Most of the validation problems we may encounter are payload validation failures, for example:
73+
74+
#### Lifetime
75+
76+
If the token in your request has expired, the validation will fail. You will see the exception information like `IDX10230` in the log.
77+
78+
#### Audience
79+
80+
The `ValidAudience` of `TokenValidationParameters` is `MyProjectName`, the `aud` in the payload of the token is also `MyProjectName`, if the token does not contain `aud` or the `aud` does not match, the validation will fail. You may see the exception information like `IDX10206`, `IDX10277` or `IDX10208`.
81+
82+
> If the `ValidateAudience` of `TokenValidationParameters` is `false`, then the `aud` will not be validated.
83+
84+
#### Issuer
85+
86+
The default value of `TokenValidationParameters.ValidateIssuer` is `true`, it requires the token's payload to contain the `issuer` field, and it must match one of `TokenValidationParameters.ValidIssuer` or `TokenValidationParameters.ValidIssuers`.
87+
88+
> The default value of `ValidIssuer` or `ValidIssuers` is `null`, it will use the `issuer` from the `OpenID Connect` metadata as the default value.
89+
90+
1. If the token's payload does not contain the `issuer` field, you may see the error `IDX10211`.
91+
2. If the API website cannot get the `OpenID Connect` metadata from AuthServer website, the validation will fail. You may see the error `IDX10204`, the full exception message is: `IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.`
92+
3. If the `issuer` does not match, the validation will fail. You may see the error `IDX10205` in the log.
93+
94+
> If the `ValidateIssuer` of `TokenValidationParameters` is `false`, then the `issuer` will not be validated.
95+
96+
> Please note that `OpenIddict` will use the current HTTP request information as the value of `issuer`. If the AuthServer website is deployed behind a reverse proxy or similar deployment configurations, the `issuer` in the token may not be the value you expect. In this case, please specify it manually.
97+
98+
```csharp
99+
PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
100+
{
101+
serverBuilder.SetIssuer("https://localhost:44301/");
102+
});
103+
```
104+
105+
## Troubleshooting
106+
107+
To troubleshoot any `IDX` errors during JWT authentication, you can enable detailed logging by configuring the `identitymodel` logs as follows:
108+
109+
```csharp
110+
using System.Diagnostics.Tracing;
111+
using Microsoft.IdentityModel.Logging;
112+
113+
public class Program
114+
{
115+
public async static Task<int> Main(string[] args)
116+
{
117+
IdentityModelEventSource.ShowPII = true;
118+
IdentityModelEventSource.Logger.LogLevel = EventLevel.Verbose;
119+
var wilsonTextLogger = newTextWriterEventListener("Logs/identitymodel.txt");
120+
wilsonTextLogger.EnableEvents(IdentityModelEventSource.Logger, EventLevel.Verbose);
121+
122+
//...
123+
}
124+
}
125+
```
126+
127+
Additionally, you can enable `OpenIddict`'s `Verbose` logs for more detailed debugging information:
128+
129+
```csharp
130+
var loggerConfiguration = new LoggerConfiguration()
131+
.MinimumLevel.Debug()
132+
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
133+
.MinimumLevel.Override("OpenIddict", LogEventLevel.Verbose)
134+
.Enrich.FromLogContext()
135+
.WriteTo.Async(c => c.File("Logs/logs.txt"))
136+
```
137+
138+
## Summary
139+
140+
For JWT authentication, you need to pay attention to the following key points:
141+
142+
1. Ensure your API website can communicate with the AuthServer properly
143+
2. Verify that the `aud` claim in your token matches the expected audience
144+
3. Confirm that the `issuer` claim in your token is valid and matches the configuration
145+
146+
You can customize the `JwtBearerOptions`'s `TokenValidationParameters` to modify the validation rules to meet your actual needs.
147+
148+
For example, if your `issuer` needs to support multiple subdomains, you can use the [Owl.TokenWildcardIssuerValidator](https://github.com/maliming/Owl.TokenWildcardIssuerValidator) library to customize the validation.
149+
150+
```csharp
151+
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
152+
.AddJwtBearer(options =>
153+
{
154+
options.Authority = "https://abp.io";
155+
options.Audience = "abp_io";
156+
157+
options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
158+
options.TokenValidationParameters.ValidIssuers = new[]
159+
{
160+
"https://{0}.abp.io"
161+
};
162+
});
163+
```
164+
165+
## References
166+
167+
- [Configure JWT bearer authentication in ASP.NET Core]([https://learn.microsoft.com/en-us/aspnet/core/security/authentication/jwt-auth?view=aspnetcore-8.0](https://learn.microsoft.com/en-us/aspnet/core/security/authentication/configure-jwt-bearer-authentication))
168+
- [OpenIddict](https://github.com/openiddict/openiddict-core)
169+
- [IdentityModel](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet)
170+
- [Owl.TokenWildcardIssuerValidator](https://github.com/maliming/Owl.TokenWildcardIssuerValidator)
67.9 KB
Loading
228 KB
Loading

0 commit comments

Comments
 (0)