Oauth EntraID with automatic user creation

Hi,

I’m new to Gitea and I’m really struggling to setup an instance on Windows with LetsEncrypt SSL certificate and Entra ID as authentication provider with automatic user creation.

By now I have a running instance on an English Windows Server 2025 with an IIS reverse proxy and a Let’s Encrypt Certificate. The server is hardened with most of the CIS recommendations.

I tried to configure Entra ID Sign-In with this (which is exactly what I want) but no matter what I tried I always end up here:

When I create the account manually, I can login successfully but I’m not part of the desired organization.

This is my config (domain name redacted):

Gitea located in „C:\program files\gitea\“

Version 1.27

App.ini

APP_NAME = Teal Gitea
RUN_USER = Gitea$
WORK_PATH = C:\Program Files\Gitea
RUN_MODE = prod

[database]
DB_TYPE = sqlite3
HOST = 127.0.0.1:3306
NAME = gitea
USER = gitea
PASSWD = 
SCHEMA = 
SSL_MODE = disable
PATH = C:\Program Files\Gitea\data\gitea.db
LOG_SQL = false

[repository]
ROOT = C:/Program Files/Gitea/data/gitea-repositories

[server]
SSH_DOMAIN = localhost
DOMAIN = localhost
HTTP_PORT = 3000
ROOT_URL = https://gitea.domain.de/
APP_DATA_PATH = C:\Program Files\Gitea\data
DISABLE_SSH = false
SSH_PORT = 22
LFS_START_SERVER = true
LFS_JWT_SECRET = secret
OFFLINE_MODE = true

[lfs]
PATH = C:/Program Files/Gitea/data/lfs

[mailer]
ENABLED = false

[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = true
ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = true
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[cron.update_checker]
ENABLED = true

[session]
PROVIDER = file

[log]
MODE = file
LEVEL = debug
ROOT_PATH = C:/Program Files/Gitea/log
LOG_ROTATE = TRUE
DAILY_ROTATE = TRUE
MAX_DAYS = 7

[repository.pull-request]
DEFAULT_MERGE_STYLE = merge

[repository.signing]
DEFAULT_TRUST_MODEL = committer

[security]
INSTALL_LOCK = true
INTERNAL_TOKEN = token
PASSWORD_HASH_ALGO = pbkdf2

; ;JWT_SECRET = secret
ENABLE_AUTO_REGISTRATION = true
; ;ACCESS_TOKEN_EXPIRATION_TIME = 36000


[oauth2]
JWT_SECRET = secret
ENABLE_AUTO_REGISTRATION = true
USERNAME = preferred_username
ACCOUNT_LINKING = auto
OPENID_CONNECT_SCOPES = openid profile email
UPDATE_AVATAR = true
REGISTER_EMAIL_CONFIRM = false

[time]
DEFAULT_UI_LOCATION = Europe/Berlin

IIS

IIS hast he following two options configured:

„system.webServer/proxy“: „preserveHostHeader“ = true

„system.webServer/proxy“: „reverseRewriteHostInResponseHeaders = false

Web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <httpRuntime requestPathInvalidCharacters="" />
    </system.web>
    <system.webServer>
        <security>
          <requestFiltering>
            <hiddenSegments>
              <clear />
            </hiddenSegments>
            <denyUrlSequences>
              <clear />
            </denyUrlSequences>
            <fileExtensions allowUnlisted="true">
              <clear />
            </fileExtensions>
          </requestFiltering>
        </security>
        <rewrite>
            <rules useOriginalURLEncoding="false">
                <rule name="ReverseProxyInboundRule1" stopProcessing="true">
                    <match url="(.*)" />
                    <action type="Rewrite" url="http://127.0.0.1:3000{UNENCODED_URL}" />
                    <serverVariables>
                        <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="HTTP_ACCEPT_ENCODING" />
                        <set name="HTTP_ACCEPT_ENCODING" value="" />
                        <set name="HTTP_X_FORWARDED_PROTO" value="https" />			
                    </serverVariables>
                </rule>
            </rules>
            <outboundRules>
                <rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
                    <!-- set the pattern correctly here - if you only want to accept http or https -->
                    <!-- change the pattern and the action value as appropriate -->
                    <match filterByTags="A, Form, Img" pattern="^http(s)?://127.0.0.1:3000/(.*)" />
                    <action type="Rewrite" value="https://gitea.domain.de/{R:2}" />
                </rule>
                <rule name="RestoreAcceptEncoding" preCondition="NeedsRestoringAcceptEncoding">
                    <match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" />
                    <action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" />
                </rule>
                <preConditions>
                    <preCondition name="ResponseIsHtml1">
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
                    </preCondition>
                    <preCondition name="NeedsRestoringAcceptEncoding">
                        <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>
        <urlCompression doDynamicCompression="true" />
        <!-- Map all extensions to the same MIME type, so all files can be
               downloaded. -->
        <staticContent>
          <clear />
          <mimeMap fileExtension="*" mimeType="application/octet-stream" />
        </staticContent>
    </system.webServer>
</configuration>

Azure App

Gitea Authentication Provider

Any help appreciated

Alex

With Gitea 1.27, Entra auto-registration creates the user but does not grant organization membership from claims alone. Check the account’s email and username mapping first, then add that user to the organization.

Hi Blake,

thank you for you response but the user is not created.
From the other post: “I’d compare the claim names there with the values Gitea reads for username and email before changing IIS again.”

How can I see what Gitea reads?

Thanks

Alex

Here is the log (debug) for one signin

This post describes the exact same behavior but the solution mention does not work for me OIDC (Microsoft Entra ID) login always redirects to /user/link_account instead of auto-registering users - Ecosystem - Gitea

Regards

Alex