aboutsummaryrefslogtreecommitdiffstats
path: root/models/auth
Commit message (Collapse)AuthorAgeFilesLines
* Enable tenv and testifylint rules (#32852)TheFox0x72024-12-151-2/+2
| | | | Enables tenv and testifylint linters closes: https://github.com/go-gitea/gitea/issues/32842
* Fix: passkey login not working anymore (#32623)hiifong2024-11-261-1/+21
| | | | | | | Quick fix #32595, use authenticator auth flags to login --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* Fix nuget/conan/container packages upload bugs (#31967)Lunny Xiao2024-09-051-0/+16
|
* add skip secondary authorization option for public oauth2 clients (#31454)Denys Konovalov2024-07-191-19/+24
|
* allow synchronizing user status from OAuth2 login providers (#31572)Rowan Bohde2024-07-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This leverages the existing `sync_external_users` cron job to synchronize the `IsActive` flag on users who use an OAuth2 provider set to synchronize. This synchronization is done by checking for expired access tokens, and using the stored refresh token to request a new access token. If the response back from the OAuth2 provider is the `invalid_grant` error code, the user is marked as inactive. However, the user is able to reactivate their account by logging in the web browser through their OAuth2 flow. Also changed to support this is that a linked `ExternalLoginUser` is always created upon a login or signup via OAuth2. ### Notes on updating permissions Ideally, we would also refresh permissions from the configured OAuth provider (e.g., admin, restricted and group mappings) to match the implementation of LDAP. However, the OAuth library used for this `goth`, doesn't seem to support issuing a session via refresh tokens. The interface provides a [`RefreshToken` method](https://github.com/markbates/goth/blob/master/provider.go#L20), but the returned `oauth.Token` doesn't implement the `goth.Session` we would need to call `FetchUser`. Due to specific implementations, we would need to build a compatibility function for every provider, since they cast to concrete types (e.g. [Azure](https://github.com/markbates/goth/blob/master/providers/azureadv2/azureadv2.go#L132)) --------- Co-authored-by: Kyle D <kdumontnu@gmail.com>
* Add Passkey login support (#31504)Anbraten2024-06-291-1/+1
| | | | | | | | | | | | | | | | closes #22015 After adding a passkey, you can now simply login with it directly by clicking `Sign in with a passkey`. ![Screenshot from 2024-06-26 12-18-17](https://github.com/go-gitea/gitea/assets/6918444/079013c0-ed70-481c-8497-4427344bcdfc) Note for testing. You need to run gitea using `https` to get the full passkeys experience. --------- Co-authored-by: silverwind <me@silverwind.io>
* Fix wrong table name (#30557)Lunny Xiao2024-04-231-2/+0
| | | | | | The table name should be `oauth2_application` but `o_auth2_application` Caused by https://github.com/go-gitea/gitea/pull/21316/files#diff-9610efbc608a41f1f2eaff5790423f0a187906f6ff0beb23a5e8d18366cc2ccfR38
* chore: use errors.New to replace fmt.Errorf with no parameters will much ↵Cheng2024-04-211-1/+2
| | | | | better (#30621) use errors.New to replace fmt.Errorf with no parameters will much better
* Add comment for ContainsRedirectURI about the exact match (#30457)wxiaoguang2024-04-131-0/+5
| | | | Close #26897 Replace #30336
* remove util.OptionalBool and related functions (#29513)65432024-03-021-4/+5
| | | | | | and migrate affected code _last refactoring bits to replace **util.OptionalBool** with **optional.Option[bool]**_
* Use `crypto/sha256` (#29386)KN4CK3R2024-02-251-1/+1
| | | | | | | | Go 1.21 improved the performance of `crypto/sha256`. It's now similar to `minio/sha256-simd`, so we should just use the standard libs. https://go.dev/doc/go1.21#crypto/sha256 https://go-review.googlesource.com/c/go/+/408795 https://github.com/multiformats/go-multihash/pull/173
* Revert "Support SAML authentication (#25165)" (#29358)65432024-02-242-43/+15
| | | | | | | | | | This reverts #25165 (5bb8d1924d77c675467694de26697b876d709a17), as there was a chance some important reviews got missed. so after reverting this patch it will be resubmitted for reviewing again https://github.com/go-gitea/gitea/pull/25165#issuecomment-1960670242 temporary Open #5512 again
* Support SAML authentication (#25165)techknowlogick2024-02-232-15/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Closes https://github.com/go-gitea/gitea/issues/5512 This PR adds basic SAML support - Adds SAML 2.0 as an auth source - Adds SAML configuration documentation - Adds integration test: - Use bare-bones SAML IdP to test protocol flow and test account is linked successfully (only runs on Postgres by default) - Adds documentation for configuring and running SAML integration test locally Future PRs: - Support group mapping - Support auto-registration (account linking) Co-Authored-By: @jackHay22 --------- Co-authored-by: jackHay22 <jack@allspice.io> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: KN4CK3R <admin@oldschoolhack.me> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Jason Song <i@wolfogre.com> Co-authored-by: morphelinho <morphelinho@users.noreply.github.com> Co-authored-by: Zettat123 <zettat123@gmail.com> Co-authored-by: Yarden Shoham <git@yardenshoham.com> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: silverwind <me@silverwind.io>
* Unify password changing and invalidate auth tokens (#27625)KN4CK3R2024-02-041-0/+5
| | | | - Unify the password changing code - Invalidate existing auth tokens when changing passwords
* Move more functions to db.Find (#28419)Lunny Xiao2024-01-151-2/+1
| | | | | | | | | Following #28220 This PR move more functions to use `db.Find`. --------- Co-authored-by: delvh <dev.lh@web.de>
* Avoid cycle-redirecting user/login page (#28636)wxiaoguang2023-12-301-5/+1
| | | | Fix #28231, and remove some unused code. The `db.HasEngine` doesn't seem useful because the db engine is always initialized before web route.
* Fix session key conflict with database keyword (#28613)Lunny Xiao2023-12-271-7/+10
| | | | | | | | | This is a regression from #28220 . `builder.Cond` will not add `` ` `` automatically but xorm method `Get/Find` adds `` ` ``. This PR also adds tests to prevent the method from being implemented incorrectly. The tests are added in `integrations` to test every database.
* Remove GetByBean method because sometimes it's danger when query condition ↵Lunny Xiao2023-12-072-24/+15
| | | | | | | | | | | | | | | | | | | | parameter is zero and also introduce new generic methods (#28220) The function `GetByBean` has an obvious defect that when the fields are empty values, it will be ignored. Then users will get a wrong result which is possibly used to make a security problem. To avoid the possibility, this PR removed function `GetByBean` and all references. And some new generic functions have been introduced to be used. The recommand usage like below. ```go // if query an object according id obj, err := db.GetByID[Object](ctx, id) // query with other conditions obj, err := db.Get[Object](ctx, builder.Eq{"a": a, "b":b}) ```
* Use db.Find instead of writing methods for every object (#28084)Lunny Xiao2023-11-245-71/+52
| | | | For those simple objects, it's unnecessary to write the find and count methods again and again.
* Fix wrong xorm Delete usage (#27995)Nanguan Lin2023-11-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ## Bug in Gitea I ran into this bug when I accidentally used the wrong redirect URL for the oauth2 provider when using mssql. But the oauth2 provider still got added. Most of the time, we use `Delete(&some{id: some.id})` or `In(condition).Delete(&some{})`, which specify the conditions. But the function uses `Delete(source)` when `source.Cfg` is a `TEXT` field and not empty. This will cause xorm `Delete` function not working in mssql. https://github.com/go-gitea/gitea/blob/61ff91f9603806df2505907614b9006bf721b9c8/models/auth/source.go#L234-L240 ## Reason Because the `TEXT` field can not be compared in mssql, xorm doesn't support it according to [this PR](https://gitea.com/xorm/xorm/pulls/2062) [related code](https://gitea.com/xorm/xorm/src/commit/b23798dc987af776bec867f4537ca129fd66328e/internal/statements/statement.go#L552-L558) in xorm ```go if statement.dialect.URI().DBType == schemas.MSSQL && (col.SQLType.Name == schemas.Text ||   col.SQLType.IsBlob() || col.SQLType.Name == schemas.TimeStampz) {   if utils.IsValueZero(fieldValue) {   continue   }   return nil, fmt.Errorf("column %s is a TEXT type with data %#v which cannot be as compare condition", col.Name, fieldValue.Interface())   } } ``` When using the `Delete` function in xorm, the non-empty fields will auto-set as conditions(perhaps some special fields are not?). If `TEXT` field is not empty, xorm will return an error. I only found this usage after searching, but maybe there is something I missing. --------- Co-authored-by: delvh <dev.lh@web.de>
* Refactor Find Sources and fix bug when view a user who belongs to an ↵Lunny Xiao2023-11-032-37/+21
| | | | | | | | | | | | unactive auth source (#27798) The steps to reproduce it. First, create a new oauth2 source. Then, a user login with this oauth2 source. Disable the oauth2 source. Visit users -> settings -> security, 500 will be displayed. This is because this page only load active Oauth2 sources but not all Oauth2 sources.
* Final round of `db.DefaultContext` refactor (#27587)JakobDev2023-10-142-15/+15
| | | Last part of #27065
* Enhanced auth token / remember me (#27606)KN4CK3R2023-10-145-0/+60
| | | | | | | | | | | | | | | | | Closes #27455 > The mechanism responsible for long-term authentication (the 'remember me' cookie) uses a weak construction technique. It will hash the user's hashed password and the rands value; it will then call the secure cookie code, which will encrypt the user's name with the computed hash. If one were able to dump the database, they could extract those two values to rebuild that cookie and impersonate a user. That vulnerability exists from the date the dump was obtained until a user changed their password. > > To fix this security issue, the cookie could be created and verified using a different technique such as the one explained at https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#secure-remember-me-cookies. The PR removes the now obsolete setting `COOKIE_USERNAME`.
* Penultimate round of `db.DefaultContext` refactor (#27414)JakobDev2023-10-112-24/+25
| | | | | | | Part of #27065 --------- Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
* Pre-register OAuth application for tea (#27509)M Hickford2023-10-081-0/+5
| | | | | | It remains to implement OAuth login in tea https://gitea.com/gitea/tea/issues/598 Fixes #27510
* make writing main test easier (#27270)Lunny Xiao2023-09-281-4/+1
| | | | | | | | | This PR removed `unittest.MainTest` the second parameter `TestOptions.GiteaRoot`. Now it detects the root directory by current working directory. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* Next round of `db.DefaultContext` refactor (#27089)JakobDev2023-09-163-64/+34
| | | Part of #27065
* More refactoring of `db.DefaultContext` (#27083)JakobDev2023-09-153-42/+45
| | | Next step of #27065
* move repository deletion to service layer (#26948)Lunny Xiao2023-09-081-0/+1
| | | Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* Ignore the trailing slashes when comparing oauth2 redirect_uri (#26597)wxiaoguang2023-08-212-2/+23
| | | Fix #26526
* Pre-register OAuth2 applications for git credential helpers (#26291)Denys Konovalov2023-08-091-0/+91
| | | | | | | | | | | | | | | | | | | | | | | | | | This PR is an extended implementation of #25189 and builds upon the proposal by @hickford in #25653, utilizing some ideas proposed internally by @wxiaoguang. Mainly, this PR consists of a mechanism to pre-register OAuth2 applications on startup, which can be enabled or disabled by modifying the `[oauth2].DEFAULT_APPLICATIONS` parameter in app.ini. The OAuth2 applications registered this way are being marked as "locked" and neither be deleted nor edited over UI to prevent confusing/unexpected behavior. Instead, they're being removed if no longer enabled in config. ![grafik](https://github.com/go-gitea/gitea/assets/47871822/81a78b1c-4b68-40a7-9e99-c272ebb8f62e) The implemented mechanism can also be used to pre-register other OAuth2 applications in the future, if wanted. Co-authored-by: hickford <mirth.hickford@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> --------- Co-authored-by: M Hickford <mirth.hickford@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* Remove "misc" scope check from public API endpoints (#26134)wxiaoguang2023-07-261-1/+1
| | | Fix #26035
* Upgrade go dependencies (#25819)harryzcy2023-07-141-6/+6
|
* Less naked returns (#25713)65432023-07-071-3/+4
| | | | | just a step towards #25655 and some related refactoring
* Add ability to set multiple redirect URIs in OAuth application UI (#25072)Denys Konovalov2023-06-051-8/+0
| | | | | | | | | | | | | | | | | | | | OAuth applications can already have multiple redirect URIs if created/edited over API. This change allows for setting multiple redirect URIs through the UI as a comma-separated list (e. g. `https://example.org/redirect,https://redirect.example.org`) <details> <summary>Screenshots</summary> ![Bildschirmfoto vom 2023-06-04 17-14-40](https://github.com/go-gitea/gitea/assets/47871822/2206dc32-e7e4-4953-9ecb-e098890b3f54) ![Bildschirmfoto vom 2023-06-04 17-14-50](https://github.com/go-gitea/gitea/assets/47871822/cd97c73c-9310-44ee-a83a-b927a1ef94da) </details> Closes #25068
* Redesign Scoped Access Tokens (#24767)Jack Hay2023-06-043-187/+276
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ## Changes - Adds the following high level access scopes, each with `read` and `write` levels: - `activitypub` - `admin` (hidden if user is not a site admin) - `misc` - `notification` - `organization` - `package` - `issue` - `repository` - `user` - Adds new middleware function `tokenRequiresScopes()` in addition to `reqToken()` - `tokenRequiresScopes()` is used for each high-level api section - _if_ a scoped token is present, checks that the required scope is included based on the section and HTTP method - `reqToken()` is used for individual routes - checks that required authentication is present (but does not check scope levels as this will already have been handled by `tokenRequiresScopes()` - Adds migration to convert old scoped access tokens to the new set of scopes - Updates the user interface for scope selection ### User interface example <img width="903" alt="Screen Shot 2023-05-31 at 1 56 55 PM" src="https://github.com/go-gitea/gitea/assets/23248839/654766ec-2143-4f59-9037-3b51600e32f3"> <img width="917" alt="Screen Shot 2023-05-31 at 1 56 43 PM" src="https://github.com/go-gitea/gitea/assets/23248839/1ad64081-012c-4a73-b393-66b30352654c"> ## tokenRequiresScopes Design Decision - `tokenRequiresScopes()` was added to more reliably cover api routes. For an incoming request, this function uses the given scope category (say `AccessTokenScopeCategoryOrganization`) and the HTTP method (say `DELETE`) and verifies that any scoped tokens in use include `delete:organization`. - `reqToken()` is used to enforce auth for individual routes that require it. If a scoped token is not present for a request, `tokenRequiresScopes()` will not return an error ## TODO - [x] Alphabetize scope categories - [x] Change 'public repos only' to a radio button (private vs public). Also expand this to organizations - [X] Disable token creation if no scopes selected. Alternatively, show warning - [x] `reqToken()` is missing from many `POST/DELETE` routes in the api. `tokenRequiresScopes()` only checks that a given token has the correct scope, `reqToken()` must be used to check that a token (or some other auth) is present. - _This should be addressed in this PR_ - [x] The migration should be reviewed very carefully in order to minimize access changes to existing user tokens. - _This should be addressed in this PR_ - [x] Link to api to swagger documentation, clarify what read/write/delete levels correspond to - [x] Review cases where more than one scope is needed as this directly deviates from the api definition. - _This should be addressed in this PR_ - For example: ```go m.Group("/users/{username}/orgs", func() { m.Get("", reqToken(), org.ListUserOrgs) m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), context_service.UserAssignmentAPI()) ``` ## Future improvements - [ ] Add required scopes to swagger documentation - [ ] Redesign `reqToken()` to be opt-out rather than opt-in - [ ] Subdivide scopes like `repository` - [ ] Once a token is created, if it has no scopes, we should display text instead of an empty bullet point - [ ] If the 'public repos only' option is selected, should read categories be selected by default Closes #24501 Closes #24799 Co-authored-by: Jonathan Tran <jon@allspice.io> Co-authored-by: Kyle D <kdumontnu@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
* Fix 500 error if there is a name conflict when edit authentication source ↵yp053272023-03-311-1/+8
| | | | (#23832)
* Add user webhooks (#21563)KN4CK3R2023-03-102-4/+10
| | | | | | | Currently we can add webhooks for organizations but not for users. This PR adds the latter. You can access it from the current users settings. ![grafik](https://user-images.githubusercontent.com/1666336/197391408-15dfdc23-b476-4d0c-82f7-9bc9b065988f.png)
* Use minio/sha256-simd for accelerated SHA256 (#23052)zeripath2023-02-222-2/+2
| | | | | | | | | | | | minio/sha256-simd provides additional acceleration for SHA256 using AVX512, SHA Extensions for x86 and ARM64 for ARM. It provides a drop-in replacement for crypto/sha256 and if the extensions are not available it falls back to standard crypto/sha256. --------- Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: John Olheiser <john.olheiser@gmail.com>
* Add scopes to API to create token and display them (#22989)zeripath2023-02-201-3/+22
| | | | | | | | The API to create tokens is missing the ability to set the required scopes for tokens, and to show them on the API and on the UI. This PR adds this functionality. Signed-off-by: Andrew Thornton <art27@cantab.net>
* Support scoped access tokens (#20908)Chongyi Zheng2023-01-173-0/+336
| | | | | | | | | | | | | | | | | | | | | | | | | | | This PR adds the support for scopes of access tokens, mimicking the design of GitHub OAuth scopes. The changes of the core logic are in `models/auth` that `AccessToken` struct will have a `Scope` field. The normalized (no duplication of scope), comma-separated scope string will be stored in `access_token` table in the database. In `services/auth`, the scope will be stored in context, which will be used by `reqToken` middleware in API calls. Only OAuth2 tokens will have granular token scopes, while others like BasicAuth will default to scope `all`. A large amount of work happens in `routers/api/v1/api.go` and the corresponding `tests/integration` tests, that is adding necessary scopes to each of the API calls as they fit. - [x] Add `Scope` field to `AccessToken` - [x] Add access control to all API endpoints - [x] Update frontend & backend for when creating tokens - [x] Add a database migration for `scope` column (enable 'all' access to past tokens) I'm aiming to complete it before Gitea 1.19 release. Fixes #4300
* Replace deprecated Webauthn library (#22400)techknowlogick2023-01-112-2/+2
| | | | | Fix #22052 Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
* Improve utils of slices (#22379)Jason Song2023-01-111-2/+2
| | | | | | | | | | | | | | | | | | | - Move the file `compare.go` and `slice.go` to `slice.go`. - Fix `ExistsInSlice`, it's buggy - It uses `sort.Search`, so it assumes that the input slice is sorted. - It passes `func(i int) bool { return slice[i] == target })` to `sort.Search`, that's incorrect, check the doc of `sort.Search`. - Conbine `IsInt64InSlice(int64, []int64)` and `ExistsInSlice(string, []string)` to `SliceContains[T]([]T, T)`. - Conbine `IsSliceInt64Eq([]int64, []int64)` and `IsEqualSlice([]string, []string)` to `SliceSortedEqual[T]([]T, T)`. - Add `SliceEqual[T]([]T, T)` as a distinction from `SliceSortedEqual[T]([]T, T)`. - Redesign `RemoveIDFromList([]int64, int64) ([]int64, bool)` to `SliceRemoveAll[T]([]T, T) []T`. - Add `SliceContainsFunc[T]([]T, func(T) bool)` and `SliceRemoveAllFunc[T]([]T, func(T) bool)` for general use. - Add comments to explain why not `golang.org/x/exp/slices`. - Add unit tests.
* Use random bytes to generate access token (#21959)Jason Song2022-11-281-3/+6
|
* Replace fmt.Sprintf with hex.EncodeToString (#21960)Jason Song2022-11-281-1/+2
| | | | | | | | | | | | | | | | | | | | | `hex.EncodeToString` has better performance than `fmt.Sprintf("%x", []byte)`, we should use it as much as possible. I'm not an extreme fan of performance, so I think there are some exceptions: - `fmt.Sprintf("%x", func(...)[N]byte())` - We can't slice the function return value directly, and it's not worth adding lines. ```diff func A()[20]byte { ... } - a := fmt.Sprintf("%x", A()) - a := hex.EncodeToString(A()[:]) // invalid + tmp := A() + a := hex.EncodeToString(tmp[:]) ``` - `fmt.Sprintf("%X", []byte)` - `strings.ToUpper(hex.EncodeToString(bytes))` has even worse performance.
* Implement FSFE REUSE for golang files (#21840)flynnnnnnnnnn2022-11-2711-22/+11
| | | | | | | | | Change all license headers to comply with REUSE specification. Fix #16132 Co-authored-by: flynnnnnnnnnn <flynnnnnnnnnn@github> Co-authored-by: John Olheiser <john.olheiser@gmail.com>
* Add index for access_token (#21908)Jason Song2022-11-231-1/+1
| | | | The `token_last_eight` field has been used in `GetAccessTokenBySHA `:
* Allow detect whether it's in a database transaction for a context.Context ↵Lunny Xiao2022-11-122-4/+4
| | | | | | | | | | | | | | | | (#21756) Fix #19513 This PR introduce a new db method `InTransaction(context.Context)`, and also builtin check on `db.TxContext` and `db.WithTx`. There is also a new method `db.AutoTx` has been introduced but could be used by other PRs. `WithTx` will always open a new transaction, if a transaction exist in context, return an error. `AutoTx` will try to open a new transaction if no transaction exist in context. That means it will always enter a transaction if there is no error. Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: 6543 <6543@obermui.de>
* Replace all instances of fmt.Errorf(%v) with fmt.Errorf(%w) (#21551)delvh2022-10-242-2/+2
| | | | | | | | | Found using `find . -type f -name '*.go' -print -exec vim {} -c ':%s/fmt\.Errorf(\(.*\)%v\(.*\)err/fmt.Errorf(\1%w\2err/g' -c ':wq' \;` Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Andrew Thornton <art27@cantab.net> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
* Record OAuth client type at registration (#21316)M Hickford2022-10-242-25/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The OAuth spec [defines two types of client](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1), confidential and public. Previously Gitea assumed all clients to be confidential. > OAuth defines two client types, based on their ability to authenticate securely with the authorization server (i.e., ability to > maintain the confidentiality of their client credentials): > > confidential > Clients capable of maintaining the confidentiality of their credentials (e.g., client implemented on a secure server with > restricted access to the client credentials), or capable of secure client authentication using other means. > > **public > Clients incapable of maintaining the confidentiality of their credentials (e.g., clients executing on the device used by the resource owner, such as an installed native application or a web browser-based application), and incapable of secure client authentication via any other means.** > > The client type designation is based on the authorization server's definition of secure authentication and its acceptable exposure levels of client credentials. The authorization server SHOULD NOT make assumptions about the client type. https://datatracker.ietf.org/doc/html/rfc8252#section-8.4 > Authorization servers MUST record the client type in the client registration details in order to identify and process requests accordingly. Require PKCE for public clients: https://datatracker.ietf.org/doc/html/rfc8252#section-8.1 > Authorization servers SHOULD reject authorization requests from native apps that don't use PKCE by returning an error message Fixes #21299 Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>