1

I am trying to add Azure Redis Cache to my .NET 8 api. I added the connectionString and added the code as:

services.AddStackExchangeRedisCache(
    options =>
    {
        options.Configuration = builder.Configuration.GetConnectionString("RedisCache");
        options.InstanceName = builder.Environment.EnvironmentName;
    })
.AddDistributedMemoryCache();

This is working when I added my password in the connectionString. But I do not want to do this, I want to use Entra ID authentication. So I have enabled the option, and also selected the web app (also in azure) which needs to use it. Access Policy as data owner. But when I leave out the password, I am getting an error:

StackExchange.Redis.RedisConnectionException: 'The message timed out in the backlog attempting to send because no connection became available (5000ms) - Last Connection Exception: AuthenticationFailure on tsg-pas-dev-redis.redis.cache.windows.net:6380/Interactive, Flushed/ComputeResult, last: ECHO, origin: SetResult, outstanding: 0, last-read: 0s ago, last-write: 0s ago, keep-alive: 60s, state: ConnectedEstablishing, mgr: 9 of 10 available, last-heartbeat: never, global: 0s ago, v: 2.6.122.38350, command=SET, timeout: 5000, inst: 12, qu: 1, qs: 0, aw: False, bw: SpinningDown, rs: ReadAsync, ws: Flushed, in: 0, last-in: 0, cur-in: 0, sync-ops: 1, async-ops: 1, serverEndpoint: tsg-pas-dev-redis.redis.cache.windows.net:6380, conn-sec: 0.23, aoc: 0, mc: 1/1/0, mgr: 10 of 10 available, clientName: DBSX1Y6-54977(SE.Redis-v2.6.122.38350), IOCP: (Busy=1,Free=999,Min=8,Max=1000), WORKER: (Busy=1,Free=32766,Min=8,Max=32767), POOL: (Threads=15,QueuedItems=0,CompletedItems=347,Timers=3), v: 2.6.122.38350 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)'

Exception: Error: NOAUTH Authentication required. Verify if the Redis password provided is correct. Attempted command: ECHO

Any clue what I am missing? I remember with one of the other services, I had to do something in the main, to fetch/initialize the token... but no clue if it is related or not.

-- EDIT: After the answer below I made a small change so I can still use IDistributedCache, because locally i can still use MemoryCache:

public static void AddDistributedCache(this IServiceCollection services, WebApplicationBuilder builder)
{
    if (builder.Configuration["UseMemoryCache"]?.Equals("yes", StringComparison.OrdinalIgnoreCase) ?? true)
    {
        services.AddDistributedMemoryCache();
    }
    else
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.InstanceName = builder.Environment.EnvironmentName;
            options.ConnectionMultiplexerFactory = () => ConnectionMultiplexerFactory(builder);
        })
        .AddDistributedMemoryCache();
    }
}

private static async Task<IConnectionMultiplexer> ConnectionMultiplexerFactory(WebApplicationBuilder builder)
{
    var configurationOptions = await ConfigurationOptions.Parse(builder.Configuration.GetConnectionString("RedisCache")!)
        .ConfigureForAzureWithTokenCredentialAsync("XXXX", new DefaultAzureCredential());

    var connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions);

    return connectionMultiplexer;
}

The XXX needs to come from appsettings, allthough I do not understand yet why I need it. And not very handy when using multiple apps on the same redis ache instance yet I guess... But at least no passwords :) The good thing about this is that I can easily switch and also do not have to worry about multiplexer getDatabase etc...

2
  • The username is not needed anymore in the more recent versions of the package. Commented Aug 13, 2024 at 7:08
  • For those who also experienced "NOAUTH Authentication required. Verify if the Redis password provided is correct. Attempted command: ECHO", try to disable Access Keys authentication in Azure Cache for Redis resource. Commented Aug 13, 2024 at 7:09

1 Answer 1

3

Based on the documentation available here, in order to use Entra ID authentication, you would need to use Microsoft.Azure.StackExchangeRedis Nuget package.

Code sample for the same is available here: https://github.com/Azure/Microsoft.Azure.StackExchangeRedis/tree/main/sample.

From this link, sample code to use DefaultAzureCredential:

Write("Redis cache host name: ");
cacheHostName = ReadLine()?.Trim();
Write("'Username' from the 'Data Access Configuration' blade on the Azure Cache for Redis resource): ");
var username = ReadLine()?.Trim();

Write("Connecting using TokenCredential...");
configurationOptions = await ConfigurationOptions.Parse($"{cacheHostName}:6380").ConfigureForAzureWithTokenCredentialAsync(username!, new DefaultAzureCredential());
configurationOptions.AbortOnConnectFail = true; // Fail fast for the purposes of this sample. In production code, this should remain false to retry connections on startup
LogTokenEvents(configurationOptions);

connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions, connectionLog);
Sign up to request clarification or add additional context in comments.

2 Comments

ok, it looks like i have it working. perfect, thnx. Now, my last concern, why would I need to add a userName (this could be the principleId), but, I am not doing that with other services, In the portal i hand over the access, and now it looks like I need to pass over the object Id.
I made a small change so i can still use IDistributedCache: see edit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.