Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,47 @@ import android.util.Log
import com.microsoft.identity.client.Logger
import com.microsoft.identity.client.PublicClientApplication
import com.microsoft.identity.nativeauth.INativeAuthPublicClientApplication
import com.microsoft.identity.nativeauth.NativeAuthPublicClientApplicationParameters

object AuthClient : Application() {
private lateinit var authClient: INativeAuthPublicClientApplication

const val EXTRA_CLIENT_ID = "native_auth_client_id"
const val EXTRA_AUTHORITY_URL = "native_auth_authority_url"

@JvmStatic
fun getAuthClient(): INativeAuthPublicClientApplication {
return authClient
}

// Initialize the auth client with the provided clientId and authorityUrl, or with the default config file if they are not provided.
@JvmStatic
fun initialize(context: Context) {
fun initialize(context: Context, clientId: String? = null, authorityUrl: String? = null) {
Logger.getInstance().setExternalLogger { tag, logLevel, message, containsPII ->
Log.e(
"MSAL",
"$tag $logLevel $message"
)
}

authClient = PublicClientApplication.createNativeAuthPublicClientApplication(
context,
R.raw.auth_config_native_auth
)
// If clientId and authorityUrl are provided, create the auth client with the provided values. Otherwise, create the auth client with the default config file.
if (clientId != null && authorityUrl != null) {
val parameters = NativeAuthPublicClientApplicationParameters(
clientId = clientId,
authorityUrl = authorityUrl,
challengeTypes = listOf("oob", "password")
)
parameters.capabilities = listOf("mfa_required", "registration_required")

authClient = PublicClientApplication.createNativeAuthPublicClientApplication(
context,
parameters
)
} else {
authClient = PublicClientApplication.createNativeAuthPublicClientApplication(
context,
R.raw.auth_config_native_auth
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import com.azuresamples.msalnativeauthandroidkotlinsampleapp.databinding.FragmentEmailPasswordBinding
import com.microsoft.identity.client.PublicClientApplication
import com.microsoft.identity.common.java.nativeauth.providers.NativeAuthRequestInterceptor
import com.microsoft.identity.common.java.util.StringUtil
import com.microsoft.identity.nativeauth.NativeAuthRequestInterceptor
import com.microsoft.identity.nativeauth.INativeAuthPublicClientApplication
import com.microsoft.identity.nativeauth.NativeAuthPublicClientApplicationConfiguration
import com.microsoft.identity.nativeauth.parameters.NativeAuthGetAccessTokenParameters
Expand Down Expand Up @@ -120,7 +119,7 @@ class EmailPasswordSignInSignUpFragment : Fragment(), NativeAuthRequestIntercept
val actionResult: SignInResult = authClient.signIn(parameters)

binding.passwordText.text?.clear()
StringUtil.overwriteWithNull(password)
password.fill('\u0000')

when (actionResult) {
is SignInResult.Complete -> {
Expand Down Expand Up @@ -160,7 +159,7 @@ class EmailPasswordSignInSignUpFragment : Fragment(), NativeAuthRequestIntercept
val actionResult: SignUpResult = authClient.signUp(parameters)

binding.passwordText.text?.clear()
StringUtil.overwriteWithNull(password)
password.fill('\u0000')

when (actionResult) {
is SignUpResult.CodeRequired -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.azuresamples.msalnativeauthandroidkotlinsampleapp.databinding.FragmentEmailPasswordBinding
import com.microsoft.identity.client.claims.ClaimsRequest
import com.microsoft.identity.common.java.util.StringUtil
import com.microsoft.identity.nativeauth.AuthMethod
import com.microsoft.identity.nativeauth.INativeAuthPublicClientApplication
import com.microsoft.identity.nativeauth.parameters.NativeAuthGetAccessTokenParameters
Expand Down Expand Up @@ -102,7 +101,7 @@ class MFAFragment : Fragment() {
parameters.password = password
val actionResult: SignInResult = authClient.signIn(parameters)
binding.passwordText.text?.clear()
StringUtil.overwriteWithNull(password)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we wrap the StringUtil in our StringUtil (new) class for eliminating hard-coded values? Also, the other classes still call StringUtil.overwriteWithNull(password).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure what you mean exactly. The only StringUtil class I see is in common and as @antrix1989 said we shouldn't use that. Indeed, I see now that it still existed in a few places in this sample app so I've done a commit to remove it completely. Let me know if that works or we should have a new StringUtil in MSAL or something like that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can create StringUtil in our Sample App later, to move hard-coded usages but now not important thing.

password.fill('\u0000')

when (actionResult) {
is SignInResult.Complete -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class MainActivity : AppCompatActivity() {
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

AuthClient.initialize(this@MainActivity)
val clientId = intent.getStringExtra(AuthClient.EXTRA_CLIENT_ID)
val authorityUrl = intent.getStringExtra(AuthClient.EXTRA_AUTHORITY_URL)
AuthClient.initialize(this@MainActivity, clientId, authorityUrl)

val emailSignInSignUpFragment = EmailSignInSignUpFragment()
val emailPasswordSignInSignUpFragment = EmailPasswordSignInSignUpFragment()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ class SignUpAttributesFragment : Fragment() {

private fun submitAttributes() {
CoroutineScope(Dispatchers.Main).launch {
val username = binding.usernameText.text.toString()

val attributes = UserAttributes.Builder()
.flatUsername(username)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not needed?

Copy link
Copy Markdown
Contributor Author

@spetrescu84 spetrescu84 May 28, 2026

Choose a reason for hiding this comment

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

Added comment to description also - Reverted changes to flatUsername to prevent building error as PR for alias is not yet merged - AzureAD/microsoft-authentication-library-for-android#2513
Will add back once that PR is merged, but currently Sample App doesn't compile as .flatUsername is not in the MSAL package/nor this branch.

.build()

val actionResult = currentState.submitAttributes(attributes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class SignUpCodeFragment : Fragment() {
is SignUpResult.AttributesRequired -> {
// Custom implementation for Flat Username / Alias
if (actionResult.requiredAttributes.size == 1 &&
actionResult.requiredAttributes.any { it.name == "flatusername" }
actionResult.requiredAttributes.any { it.attributeName == "flatusername" }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

name also works, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

in Android Complete and pipeline it doesn't because of how it's imported

) {
navigateToAttributes(
nextState = actionResult.nextState
Expand Down