Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core Windows authentication in docker container

I want to create a container from my .NET Core web application (it consists of multiple projects) which uses Windows Authentication. Here is my Dockerfile:

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.1-sdk AS build
COPY Solution.sln ./
COPY Project1/*.csproj ./Project1/
COPY Project2/*.csproj ./Project2/
COPY Project3/*.csproj ./Project3/
COPY Project4/*.csproj ./Project4/
COPY Project5/*.csproj ./Project5/

RUN dotnet restore
COPY . .

WORKDIR /Project1
RUN dotnet build -c Release -o /app

WORKDIR /Project2
RUN dotnet build -c Release -o /app

WORKDIR /Project3
RUN dotnet build -c Release -o /app

WORKDIR /Project4
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Project4.dll"]

If I run the container, the website opens up but it doesn't open log in dialogue and user information is missing. What is the easiest way to enable Windows authentication inside Docker container?

like image 468
Mark Avatar asked Feb 13 '19 10:02

Mark


1 Answers

By nature, your container is isolated and does not belong to your domain, which makes Windows Authentication a well known issue. The way to achieve this is by using a technology Microsoft introduced recently called gMSA, https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/hh831782(v=ws.11)

About how to use it with Docker: https://www.axians-infoma.de/techblog/windows-authentication-in-docker-containers-just-got-a-lot-easier/ https://artisticcheese.wordpress.com/2017/09/09/enabling-integrated-windows-authentication-in-windows-docker-container/

Per Mark request, you could also use a piece of code using LDAP:

private bool VerifyServerCertificateCallback(LdapConnection connection, X509Certificate certificate)
{
    return new X509Certificate2(certificate).Verify();
}

public bool ValidateCredentials(string userName, string password) 
{
    try
    {
        var ldapDirectoryIdentifier = new ldapDirectoryIdentifier(ldapServer.ServerAddress);

        var ldapConnection = new LdapConnection(ldapDirectoryIdentifier)
        {
            AuthType = AuthType.Basic
        };
        ldapConnection.SessionOptions.ProtocolVersion = 3;
        ldapConnection.SessionOptions.SecureSocketLayer = true;
        ldapConnection.SessionOptions.VerifyServerCertificate = VerifyServerCertificateCallback;

        ldapConnection.Bind(new NetworkCredential(string.Format(ldapServer.UserLocation, userName), password));

        ldapConnection.Dispose();
    }
    catch (Exception exception) {
        continue;
    }
    return true;
}

And in your controller:

if (ValidateCredentials(username, password))
{
    ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(
        new List<Claim>()
        {
            new Claim(ClaimTypes.Name, username),
            //...
        },
        /*"..."*/));

    await HttpContext.SignInAsync(AuthSchemeName, principal);
}
like image 138
Daboul Avatar answered Sep 29 '22 01:09

Daboul