Migrera ett program för att använda lösenordslösa anslutningar med Azure Event Hubs för Kafka
Den här artikeln beskriver hur du migrerar från traditionella autentiseringsmetoder till säkrare, lösenordslösa anslutningar med Azure Event Hubs för Kafka.
Programbegäranden till Azure Event Hubs för Kafka måste autentiseras. Azure Event Hubs for Kafka tillhandahåller olika sätt för appar att ansluta på ett säkert sätt. Ett sätt är att använda en niska veze. Du bör dock prioritera lösenordslösa anslutningar i dina program när det är möjligt.
Lösenordslösa anslutningar stöds sedan Spring Cloud Azure 4.3.0. Den här artikeln är en migreringsguide för att ta bort autentiseringsuppgifter från Spring Cloud Stream Kafka-program.
Jämför autentiseringsalternativ
När programmet autentiseras med Azure Event Hubs för Kafka tillhandahåller det en auktoriserad entitet för att ansluta Event Hubs-namnområdet. Apache Kafka-protokoll tillhandahåller flera SASL-mekanismer (Simple Authentication and Security Layer) för autentisering. Enligt SASL-mekanismerna finns det två autentiseringsalternativ som du kan använda för att auktorisera åtkomst till dina säkra resurser: Microsoft Entra-autentisering och SAS-autentisering (Signatur för delad åtkomst).
Microsoft Entra-autentisering
Microsoft Entra-autentisering är en mekanism för att ansluta till Azure Event Hubs för Kafka med hjälp av identiteter som definierats i Microsoft Entra-ID. Med Microsoft Entra-autentisering kan du hantera tjänstens huvudnamnsidentiteter och andra Microsoft usluge på en central plats, vilket förenklar behörighetshanteringen.
Användning av Microsoft Entra-ID för autentisering ger följande fördelar:
- Autentisering av användare i Azure-tjänster på ett enhetligt sätt.
- Hantering av lösenordsprinciper och lösenordsrotation på en enda plats.
- Flera former av autentisering som stöds av Microsoft Entra-ID, vilket kan eliminera behovet av att lagra lösenord.
- Kunder kan hantera Event Hubs-behörigheter med hjälp av externa (Microsoft Entra ID)-grupper.
- Stöd för tokenbaserad autentisering för program som ansluter till Azure Event Hubs för Kafka.
SAS-autentisering
Event Hubs tillhandahåller även signaturer för delad åtkomst (SAS) för delegerad åtkomst till Event Hubs för Kafka-resurser.
Även om det är möjligt att ansluta till Azure Event Hubs för Kafka med SAS bör det användas med försiktighet. Du måste vara noggrann för att aldrig exponera niska veze på en osäker plats. Alla som får åtkomst till niska veze kan autentisera. Det finns till exempel en risk att en obehörig användare kan komma åt programmet om en niska veze av misstag checkas in i källkontrollen, skickas via ett osäkert e-postmeddelande, klistras in i fel chatt eller visas av någon som inte borde ha behörighet. I stället ger auktorisering av åtkomst med hjälp av den OAuth 2.0-tokenbaserade mekanismen överlägsen säkerhet och användarvänlighet över SAS. Överväg att uppdatera ditt program för att använda lösenordslösa anslutningar.
Introduktion till lösenordslösa anslutningar
Med en lösenordslös anslutning kan du ansluta till Azure-tjänster utan att lagra några autentiseringsuppgifter i programkoden, dess konfigurationsfiler eller i miljövariabler.
Många Azure-tjänster stöder lösenordslösa anslutningar, till exempel via Azure Managed Identity. De här teknikerna ger robusta säkerhetsfunktioner som du kan implementera med hjälp av DefaultAzureCredential från Azure Identity-klientbiblioteken. I den här självstudien får du lära dig hur du uppdaterar ett befintligt program så att det kan användas DefaultAzureCredential
i stället för alternativ som niska veze.
DefaultAzureCredential
stöder flera autentiseringsmetoder och avgör automatiskt vilka som ska användas vid körning. Med den här metoden kan din app använda olika autentiseringsmetoder i olika miljöer (lokal utveckling jämfört med produktion) utan att implementera miljöspecifik kod.
Ordningen och platserna där DefaultAzureCredential
sökningar efter autentiseringsuppgifter finns i översikten över Azure Identity Library. När du till exempel arbetar lokalt DefaultAzureCredential
autentiseras vanligtvis med det konto som utvecklaren använde för att logga in i Visual Studio. När appen distribueras till Azure DefaultAzureCredential
växlar den automatiskt till att använda en hanterad identitet. Inga kodändringar krävs för den här övergången.
För att säkerställa att anslutningarna är lösenordslösa måste du ta hänsyn till både lokal utveckling och produktionsmiljön. Om en niska veze krävs på något av dessa ställe är programmet inte lösenordslöst.
I din lokala utvecklingsmiljö kan du autentisera med Azure CLI, Azure PowerShell, Visual Studio eller Azure-plugin-program för Visual Studio Code eller IntelliJ. I det här fallet kan du använda autentiseringsuppgifterna i ditt program i stället för att konfigurera egenskaper.
När du distribuerar program till en Azure-värdmiljö, till exempel en virtuell dator, kan du tilldela hanterad identitet i den miljön. Sedan behöver du inte ange autentiseringsuppgifter för att ansluta till Azure-tjänster.
Kommentar
En hanterad identitet tillhandahåller en säkerhetsidentitet som representerar en app eller tjänst. Identiteten hanteras av Azure-plattformen och kräver inte att du etablerar eller roterar några hemligheter. Du kan läsa mer om hanterade identiteter i översiktsdokumentationen.
Migrera ett befintligt program för att använda lösenordslösa anslutningar
Följande steg beskriver hur du migrerar ett befintligt program för att använda lösenordslösa anslutningar i stället för en SAS-lösning.
0) Förbereda arbetsmiljön för lokal utvecklingsautentisering
Använd först följande kommando för att konfigurera vissa miljövariabler.
export AZ_RESOURCE_GROUP=<YOUR_RESOURCE_GROUP>
export AZ_EVENTHUBS_NAMESPACE_NAME=<YOUR_EVENTHUBS_NAMESPACE_NAME>
export AZ_EVENTHUB_NAME=<YOUR_EVENTHUB_NAME>
Ersätt platshållarna med följande värden, som används i hela artikeln:
<YOUR_RESOURCE_GROUP>
: Namnet på den resursgrupp som du ska använda.<YOUR_EVENTHUBS_NAMESPACE_NAME>
: Namnet på det Azure Event Hubs-namnområde som du ska använda.<YOUR_EVENTHUB_NAME>
: Namnet på den händelsehubb som du ska använda.
1) Bevilja behörighet för Azure Event Hubs
Om du vill köra det här exemplet lokalt med Microsoft Entra-autentisering kontrollerar du att ditt användarkonto har autentiserats via Azure Toolkit for IntelliJ, Plugin-programmet Visual Studio Code Azure-konto eller Azure CLI. Kontrollera också att kontot har beviljats tillräckliga behörigheter.
Leta upp event hubs-namnområdet i Azure-portalen med hjälp av huvudsökfältet eller det vänstra navigeringsfältet.
På översiktssidan för Event Hubs väljer du Åtkomstkontroll (IAM) på den vänstra menyn.
På sidan Åtkomstkontroll (IAM) väljer du fliken Rolltilldelningar .
Välj Lägg till på den översta menyn och sedan Lägg till rolltilldelning från den resulterande nedrullningsbara menyn.
Använd sökrutan för att filtrera resultatet till önskad roll. I det här exemplet söker du efter Azure Event Hubs Data Sender och Azure Event Hubs Data Receiver och väljer matchande resultat och väljer sedan Nästa.
Under Tilldela åtkomst till väljer du Användare, grupp eller tjänstens huvudnamn och väljer sedan Välj medlemmar.
I dialogrutan söker du efter ditt Microsoft Entra-användarnamn (vanligtvis din user@domain e-postadress) och väljer sedan Välj längst ned i dialogrutan.
Välj Granska + tilldela för att gå till den sista sidan och sedan Granska + tilldela igen för att slutföra processen.
Mer information om hur du beviljar åtkomstroller finns i Auktorisera åtkomst till Event Hubs-resurser med hjälp av Microsoft Entra-ID.
2) Logga in och migrera appkoden för att använda lösenordslösa anslutningar
För lokal utveckling kontrollerar du att du är autentiserad med samma Microsoft Entra-konto som du tilldelade rollen till på dina Event Hubs. Du kan autentisera via Azure CLI, Visual Studio, Azure PowerShell eller andra verktyg som IntelliJ.
Logga in på Azure via Azure CLI med hjälp av följande kommando:
az login
Använd sedan följande steg för att uppdatera Ditt Spring Kafka-program för att använda lösenordslösa anslutningar. Även om de är konceptuellt lika använder varje ramverk olika implementeringsinformation.
Öppna filen pom.xml i projektet och lägg till följande referens:
<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity</artifactId> <version>1.6.0</version> </dependency>
Efter migreringen implementerar du AuthenticateCallbackHandler och OAuthBearerToken i projektet för OAuth2-autentisering, enligt följande exempel.
public class KafkaOAuth2AuthenticateCallbackHandler implements AuthenticateCallbackHandler { private static final Duration ACCESS_TOKEN_REQUEST_BLOCK_TIME = Duration.ofSeconds(30); private static final String TOKEN_AUDIENCE_FORMAT = "%s://%s/.default"; private Function<TokenCredential, Mono<OAuthBearerTokenImp>> resolveToken; private final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); @Override public void configure(Map<String, ?> configs, String mechanism, List<AppConfigurationEntry> jaasConfigEntries) { TokenRequestContext request = buildTokenRequestContext(configs); this.resolveToken = tokenCredential -> tokenCredential.getToken(request).map(OAuthBearerTokenImp::new); } private TokenRequestContext buildTokenRequestContext(Map<String, ?> configs) { URI uri = buildEventHubsServerUri(configs); String tokenAudience = buildTokenAudience(uri); TokenRequestContext request = new TokenRequestContext(); request.addScopes(tokenAudience); return request; } @SuppressWarnings("unchecked") private URI buildEventHubsServerUri(Map<String, ?> configs) { String bootstrapServer = Arrays.asList(configs.get(BOOTSTRAP_SERVERS_CONFIG)).get(0).toString(); bootstrapServer = bootstrapServer.replaceAll("\\[|\\]", ""); URI uri = URI.create("https://" + bootstrapServer); return uri; } private String buildTokenAudience(URI uri) { return String.format(TOKEN_AUDIENCE_FORMAT, uri.getScheme(), uri.getHost()); } @Override public void handle(Callback[] callbacks) throws UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof OAuthBearerTokenCallback) { OAuthBearerTokenCallback oauthCallback = (OAuthBearerTokenCallback) callback; this.resolveToken .apply(credential) .doOnNext(oauthCallback::token) .doOnError(throwable -> oauthCallback.error("invalid_grant", throwable.getMessage(), null)) .block(ACCESS_TOKEN_REQUEST_BLOCK_TIME); } else { throw new UnsupportedCallbackException(callback); } } } @Override public void close() { // NOOP } }
public class OAuthBearerTokenImp implements OAuthBearerToken { private final AccessToken accessToken; private final JWTClaimsSet claims; public OAuthBearerTokenImp(AccessToken accessToken) { this.accessToken = accessToken; try { claims = JWTParser.parse(accessToken.getToken()).getJWTClaimsSet(); } catch (ParseException exception) { throw new SaslAuthenticationException("Unable to parse the access token", exception); } } @Override public String value() { return accessToken.getToken(); } @Override public Long startTimeMs() { return claims.getIssueTime().getTime(); } @Override public long lifetimeMs() { return claims.getExpirationTime().getTime(); } @Override public Set<String> scope() { // Referring to https://docs.microsoft.com/azure/active-directory/develop/access-tokens#payload-claims, the scp // claim is a String, which is presented as a space separated list. return Optional.ofNullable(claims.getClaim("scp")) .map(s -> Arrays.stream(((String) s) .split(" ")) .collect(Collectors.toSet())) .orElse(null); } @Override public String principalName() { return (String) claims.getClaim("upn"); } public boolean isExpired() { return accessToken.isExpired(); } }
När du skapar din Kafka-producent eller -konsument lägger du till den konfiguration som behövs för att stödja SASL/OAUTHBEARER-mekanismen . I följande exempel visas hur koden ska se ut före och efter migreringen. I båda exemplen
<eventhubs-namespace>
ersätter du platshållaren med namnet på ditt Event Hubs-namnområde.Innan migreringen bör koden se ut som i följande exempel:
Properties properties = new Properties(); properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, "<eventhubs-namespace>.servicebus.windows.net:9093"); properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_SSL"); properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); properties.put(SaslConfigs.SASL_MECHANISM, "PLAIN"); properties.put(SaslConfigs.SASL_JAAS_CONFIG, String.format("org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"%s\";", connectionString)); return new KafkaProducer<>(properties);
Efter migreringen bör koden se ut som i följande exempel. I det här exemplet ersätter du
<path-to-your-KafkaOAuth2AuthenticateCallbackHandler>
platshållaren med det fullständiga klassnamnet för din implementeradeKafkaOAuth2AuthenticateCallbackHandler
.Properties properties = new Properties(); properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, "<eventhubs-namespace>.servicebus.windows.net:9093"); properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_SSL"); properties.put(SaslConfigs.SASL_MECHANISM, "OAUTHBEARER"); properties.put(SaslConfigs.SASL_JAAS_CONFIG, "org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required"); properties.put(SaslConfigs.SASL_LOGIN_CALLBACK_HANDLER_CLASS, "<path-to-your-KafkaOAuth2AuthenticateCallbackHandler>"); return new KafkaProducer<>(properties);
Köra appen lokalt
När du har gjort dessa kodändringar kör du programmet lokalt. Den nya konfigurationen bör hämta dina lokala autentiseringsuppgifter, förutsatt att du är inloggad på ett kompatibelt IDE- eller kommandoradsverktyg, till exempel Azure CLI, Visual Studio eller IntelliJ. De roller som du har tilldelat till din lokala utvecklingsanvändare i Azure gör att appen kan ansluta till Azure-tjänsten lokalt.
3) Konfigurera Azure-värdmiljön
När programmet har konfigurerats för att använda lösenordslösa anslutningar och det körs lokalt kan samma kod autentisera till Azure-tjänster när det har distribuerats till Azure. Ett program som distribueras till en Azure Spring Apps-instans som har en tilldelad hanterad identitet kan till exempel ansluta till Azure Event Hubs för Kafka.
I det här avsnittet kör du två steg för att göra det möjligt för ditt program att köras i en Azure-värdmiljö på ett lösenordslöst sätt:
- Tilldela den hanterade identiteten för din Azure-värdmiljö.
- Tilldela roller till den hanterade identiteten.
Kommentar
Azure tillhandahåller även Service Connector, som kan hjälpa dig att ansluta din värdtjänst till Event Hubs. Med Service Connector för att konfigurera din värdmiljö kan du utelämna steget att tilldela roller till din hanterade identitet eftersom Service Connector gör det åt dig. I följande avsnitt beskrivs hur du konfigurerar din Azure-värdmiljö på två sätt: en via Service Connector och den andra genom att konfigurera varje värdmiljö direkt.
Viktigt!
Service Connector-kommandon kräver Azure CLI 2.41.0 eller senare.
Tilldela den hanterade identiteten för din Azure-värdmiljö
Följande steg visar hur du tilldelar en systemtilldelad hanterad identitet för olika webbvärdtjänster. Den hanterade identiteten kan på ett säkert sätt ansluta till andra Azure-tjänster med hjälp av de appkonfigurationer som du konfigurerade tidigare.
På huvudöversiktssidan för din Azure App Service-instans väljer du Identitet i navigeringsfönstret.
På fliken Systemtilldelat ser du till att ange fältet Status till på. En systemtilldelad identitet hanteras av Azure internt och hanterar administrativa uppgifter åt dig. Informationen och ID:t för identiteten visas aldrig i din kod.
Du kan också tilldela hanterad identitet i en Azure-värdmiljö med hjälp av Azure CLI.
Du kan tilldela en hanterad identitet till en Azure App Service-instans med kommandot az webapp identity assign , enligt följande exempel.
export AZURE_MANAGED_IDENTITY_ID=$(az webapp identity assign \
--resource-group $AZ_RESOURCE_GROUP \
--name <app-service-name> \
--query principalId \
--output tsv)
Tilldela roller till den hanterade identiteten
Bevilja sedan behörigheter till den hanterade identitet som du skapade för att få åtkomst till Event Hubs-namnområdet. Du kan bevilja behörigheter genom att tilldela en roll till den hanterade identiteten, precis som du gjorde med din lokala utvecklingsanvändare.
Om du har anslutit dina tjänster med hjälp av Service Connector behöver du inte slutföra det här steget. Följande nödvändiga konfigurationer hanterades åt dig:
Om du valde en hanterad identitet när du skapade anslutningen skapades en systemtilldelad hanterad identitet för din app och tilldelades rollerna Azure Event Hubs Data Sender och Azure Event Hubs Data Receiver på Event Hubs.
Om du valde att använda en niska veze lades niska veze till som en appmiljövariabel.
Testa appen
När du har gjort dessa kodändringar bläddrar du till ditt värdbaserade program i webbläsaren. Din app bör kunna ansluta till Azure Event Hubs för Kafka. Tänk på att det kan ta flera minuter innan rolltilldelningarna sprids via din Azure-miljö. Ditt program är nu konfigurerat att köras både lokalt och i en produktionsmiljö utan att utvecklarna behöver hantera hemligheter i själva programmet.
Nästa steg
I den här självstudien har du lärt dig hur du migrerar ett program till lösenordslösa anslutningar.
Du kan läsa följande resurser för att utforska begreppen som beskrivs i den här artikeln mer ingående: