Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCSP-41148 Authentication Guides #50

Merged
merged 31 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
30fb3cf
authentication v1
lindseymoore Oct 2, 2024
a2f2858
fix build
lindseymoore Oct 3, 2024
3adcdb7
add to toc
lindseymoore Oct 3, 2024
93c7361
enterprise auth ex
lindseymoore Oct 3, 2024
bb38053
broken link fix
lindseymoore Oct 3, 2024
7f14924
link fix
lindseymoore Oct 3, 2024
0201d91
link fix
lindseymoore Oct 3, 2024
a35a4d9
last link fix for auth
lindseymoore Oct 3, 2024
0e46d1f
enterprise auth links
lindseymoore Oct 3, 2024
2fe9ea3
fix
lindseymoore Oct 3, 2024
f77d104
merge
lindseymoore Oct 3, 2024
7c55fc8
enterprise standardize
lindseymoore Oct 4, 2024
a5eb728
authen remodel
lindseymoore Oct 4, 2024
bfcc820
move x509 up
lindseymoore Oct 4, 2024
09ff82a
add ref
lindseymoore Oct 16, 2024
93f7b42
remove note
lindseymoore Oct 16, 2024
e221a89
review comments
lindseymoore Oct 16, 2024
8bcf76f
fix link
lindseymoore Oct 16, 2024
015886e
first round
lindseymoore Oct 22, 2024
ade5e21
fix core api links
lindseymoore Oct 23, 2024
d75ca0a
last comments
lindseymoore Oct 23, 2024
a018a87
link run through
lindseymoore Oct 23, 2024
769c97b
quick
lindseymoore Oct 23, 2024
ecd78d8
last inernal review comments
lindseymoore Nov 1, 2024
8956505
back to standard form
lindseymoore Nov 26, 2024
ce04806
edit
lindseymoore Nov 26, 2024
8d2fb54
port as integer
lindseymoore Nov 27, 2024
307f61a
Merge branch 'master' into DOCSP-41148
lindseymoore Nov 27, 2024
21a888f
add security section
lindseymoore Nov 27, 2024
4e75710
fix sncrypt fileds toc
lindseymoore Nov 27, 2024
c4db472
add toc labels
lindseymoore Nov 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 206 additions & 0 deletions source/includes/security/authentication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import com.mongodb.*
import com.mongodb.kotlin.client.MongoClient
import org.bson.BsonInt64
import org.bson.Document

// SCRAM Authentication
// start-default-cred-string
val mongoClient =
MongoClient.create("mongodb+srv://<db_username>:<db_password>@<hostname>:<port>/?authSource=<authenticationDb>")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the SRV URI connection format is used, no port can be specified.

Also, It seems that some examples use builder.srvHost("<hostname>"), while others use builder.hosts(listOf(ServerAddress("<hostname>", <port>))). The Java driver documentation consistently uses builder.hosts(listOf(ServerAddress("<hostname>", <port>))).

Is srv host configuration used for conciseness in some examples?

I suggest we standardize the examples to use either the SRV format or the host:port format for consistency. The latter would align with the Java driver documentation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @vbabanin, I opted for the SRV URI format for the connection string examples because I get the following timeout error using the standard format. It is because ssl is not enabled:

com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=atlascluster.spm1ztf.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: atlascluster.spm1ztf.mongodb.net}, caused by {java.net.UnknownHostException: atlascluster.spm1ztf.mongodb.net}}]

For the same reason, I used builder.srvHost("<hostname>") instead of the alternative. In order to make to the examples copyable and runnable, does it make sense to use the +srv format? Thanks!

// end-default-cred-string

// start-default-mongo-cred
val credential = MongoCredential.createCredential(
"<db_username>", "<authenticationDb>", "<db_password>".toCharArray()
)

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.srvHost("<hostname>")
}
.credential(credential)
.applyToSslSettings { builder ->
builder.enabled(true)
}
.build()

val mongoClient = MongoClient.create(settings)
// end-default-mongo-cred

// start-scramsha256-cred-string
val mongoClient =
MongoClient.create("mongodb+srv://<db_username>:<db_password>@<hostname>:<port>/?authSource=admin&authMechanism=SCRAM-SHA-256")
// end-scramsha256-cred-string

// start-scramsha256-mongo-cred
val credential = MongoCredential.createScramSha256Credential(
"<db_username>", "<authenticationDb>", "<db_password>".toCharArray()
)

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.srvHost("<hostname>")
}
.applyToSslSettings { builder ->
builder.enabled(true)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-scramsha256-mongo-cred

// start-scramsha1-cred-string
val mongoClient =
MongoClient.create("mongodb+srv://<db_username>:<db_password>@<hostname>:<port>/?authSource=admin&authMechanism=SCRAM-SHA-1")
// end-scramsha1-cred-string

// start-scramsha1-mongo-cred
val credential = MongoCredential.createScramSha1Credential(
"<db_username>", "<authenticationDb>", "<db_password>".toCharArray()
)

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.srvHost("<hostname>")
}
.applyToSslSettings { builder ->
builder.enabled(true)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-scramsha1-mongo-cred

// AWS Authentication

// start-aws-sdk-mcred
val credential = MongoCredential.createAwsCredential(null, null)

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.hosts(
listOf(ServerAddress("<atlasUri>"))
)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-aws-sdk-mcred

// start-aws-sdk-cred-string
val mongoClient =
MongoClient.create("mongodb://<atlasUri>?authMechanism=MONGODB-AWS")
// end-aws-sdk-cred-string


// start-aws-env-mcred
val credential = MongoCredential.createAwsCredential(null, null)

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.hosts(
listOf(ServerAddress("<atlasUri>"))
)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-aws-env-mcred

// start-aws-env-cred-string
val mongoClient =
MongoClient.create("mongodb://<atlasUri>?authMechanism=MONGODB-AWS")
// end-aws-env-cred-string

// start-aws-mcred
val credential = MongoCredential.createAwsCredential("<awsKeyId>", "<awsSecretKey>".toCharArray())

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.hosts(
listOf(ServerAddress("<atlasUri>"))
)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-aws-mcred

// start-aws-mcred-wmechprop
val credential = MongoCredential.createAwsCredential("<awsKeyId>", "<awsSecretKey>".toCharArray())
.withMechanismProperty("AWS_SESSION_TOKEN", "<awsSessionToken>")

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder: ClusterSettings.Builder ->
builder.hosts(
listOf(ServerAddress("<atlasUri>"))
)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-aws-mcred-wmechprop

// start-aws-lambda-expression
val awsFreshCredentialSupplier: Supplier<AwsCredential> = Supplier {
// Add your code here to fetch new credentials

// Return the new credentials
AwsCredential("<awsKeyId>", "<awsSecretKey>", "<awsSessionToken>")
}

val credential = MongoCredential.createAwsCredential("<awsKeyId>", "<awsSecretKey>".toCharArray())
.withMechanismProperty(MongoCredential.AWS_CREDENTIAL_PROVIDER_KEY, awsFreshCredentialSupplier)

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
vbabanin marked this conversation as resolved.
Show resolved Hide resolved
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-aws-lambda-expression

// start-aws-apply-connect-string
val credential = MongoCredential.createAwsCredential("<awsKeyId>", "<awsSecretKey>".toCharArray())
val connectionString = ConnectionString("mongodb://<atlasUri>/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:<awsSessionToken>")

val settings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-aws-apply-connect-string

// X.509

// start-x509-connect-string
val mongoClient =
MongoClient.create("mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=MONGODB-X509&tls=true")
// end-x509-connect-string

// start-x509-mcred
val credential = MongoCredential.createMongoX509Credential()

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(
ServerAddress("<hostname>", <port>))
)
}
.applyToSslSettings { builder ->
builder.enabled(true)
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-x509-mcred
147 changes: 147 additions & 0 deletions source/includes/security/enterprise-auth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import com.mongodb.*
import com.mongodb.kotlin.client.MongoClient
import org.bson.BsonInt64
import org.bson.Document

// GSSAPI

// start-gssapi-connect-string
val connectionString = ConnectionString("<Kerberos principal>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI")
val mongoClient = MongoClient.create(connectionString)
// end-gssapi-connect-string

// start-gssapi-mongo-cred
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-gssapi-mongo-cred

// start-gssapi-properties-connect-string
val connectionString = ConnectionString("<Kerberos principal>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:myService")
val mongoClient = MongoClient.create(connectionString)
// end-gssapi-properties-connect-string

// start-gssapi-service-name-key
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
.withMechanismProperty(MongoCredential.SERVICE_NAME_KEY, "myService")
// end-gssapi-service-name-key

// start-gssapi-java-subject-key
val loginContext = LoginContext("<LoginModule implementation from JAAS config>")
loginContext.login()
val subject: Subject = loginContext.subject

val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
.withMechanismProperty(MongoCredential.JAVA_SUBJECT_KEY, subject)
// end-gssapi-java-subject-key

// start-gssapi-java-subject-provider
/* All MongoClient instances sharing this instance of KerberosSubjectProvider
will share a Kerberos ticket cache */
val myLoginContext = "myContext"
/* Login context defaults to "com.sun.security.jgss.krb5.initiate"
if unspecified in KerberosSubjectProvider */
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
.withMechanismProperty(
MongoCredential.JAVA_SUBJECT_PROVIDER_KEY,
KerberosSubjectProvider(myLoginContext)
)
// end-gssapi-java-subject-provider

// LDAP

// start-ldap-connect-string
val connectionString = ConnectionString("<LDAP username>:<password>@<hostname>:<port>/?authSource=$external&authMechanism=PLAIN")
val mongoClient = MongoClient.create(connectionString)
// end-ldap-connect-string

// start-ldap-mongo-cred
val credential = MongoCredential.createPlainCredential("<LDAP username>", "$external", "<password>".toCharArray())

val settings = MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
}
.credential(credential)
.build()

val mongoClient = MongoClient.create(settings)
// end-ldap-mongo-cred

// OIDC

// start-oidc-azure-connect-str
val connectionString = ConnectionString(
"mongodb://<OIDC principal>@<hostname>:<port>/?" +
"?authMechanism=MONGODB-OIDC" +
"&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>")
val mongoClient = MongoClient.create(connectionString)
// end-oidc-azure-connect-str

// start-oidc-azure-mongo-cred
val credential = MongoCredential.createOidcCredential("<OIDC principal>")
.withMechanismProperty("ENVIRONMENT", "azure")
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")

val mongoClient = MongoClient.create(
MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
}
.credential(credential)
.build())
// end-oidc-azure-mongo-cred

// start-oidc-gcp-connect-str
val connectionString = ConnectionString(
"mongodb://<OIDC principal>@<hostname>:<port>/?" +
"authMechanism=MONGODB-OIDC" +
"&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>")
val mongoClient = MongoClient.create(connectionString)
// end-oidc-gcp-connect-str

// start-oidc-gcp-mongo-cred
val credential = MongoCredential.createOidcCredential("<OIDC principal>")
.withMechanismProperty("ENVIRONMENT", "gcp")
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")

val mongoClient = MongoClient.create(
MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
}
.credential(credential)
.build())
// end-oidc-gcp-mongo-cred

// start-oidc-custom-callback
val credential = MongoCredential.createOidcCredential(null)
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
val accessToken = "..."
OidcCallbackResult(accessToken)
}
// end-oidc-custom-callback

// start-oidc-custom-callback-ex
val credential = MongoCredential.createOidcCredential(null)
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
val accessToken = String(Files.readAllBytes(Paths.get("access-token.dat")))
OidcCallbackResult(accessToken)
}

val mongoClient = MongoClient.create(
MongoClientSettings.builder()
.applyToClusterSettings { builder ->
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
}
.credential(credential)
.build()
)
// end-oidc-custom-callback-ex
1 change: 1 addition & 0 deletions source/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
/indexes
/aggregation
Use Aggregation Expression Operations </agg-exp-ops>
/security
/data-formats
/builders
/encrypt-fields
Expand Down
13 changes: 13 additions & 0 deletions source/security.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

================
Secure Your Data
================

.. toctree::
:titlesonly:
:maxdepth: 1

/security/authentication
/security/enterprise-auth

.. placeholder
Loading
Loading