# 4.2.2 Using user pools with Bayun AWSS3 wrapper 'SecureAuthentication'

User Registration, SignUp Confirmation, SignIn, SignOut needs to be done with **SecureAuthentication** instance.

### Set up your service config

There is no change in setting up Service Config and is same as using standard AWS Mobile SDK.

{% tabs %}
{% tab title="Java" %}

```java
// Create a user pool with default ClientConfiguration
CognitoUserPool userPool = new CognitoUserPool(context, userPoolId, clientId, clientSecret, cognitoRegion);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Create a user pool with default ClientConfiguration
    var userPool: CognitoUserPool =
        CognitoUserPool(context, userPoolId, clientId, clientSecret, cognitoRegion)
```

{% endtab %}
{% endtabs %}

OR

{% tabs %}
{% tab title="Java" %}

```java
// This will also work
ClientConfiguration clientConfiguration = new ClientConfiguration();
AmazonCognitoIdentityProvider cipClient = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), clientConfiguration);
cipClient.setRegion(Region.getRegion(cognitoRegion));
CognitoUserPool userPool = new CognitoUserPool(context, userPoolId, clientId, clientSecret, cipClient);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// This will also work
 val clientConfiguration :ClientConfiguration =  ClientConfiguration()
 val cipClient :AmazonCognitoIdentityProvider =  AmazonCognitoIdentityProviderClient( AnonymousAWSCredentials(), clientConfiguration) 
 cipClient.setRegion(Region.getRegion(cognitoRegion))
 val userPool:CognitoUserPool = CognitoUserPool(context, userPoolId, clientId, clientSecret, cipClient)
  
```

{% endtab %}
{% endtabs %}

### Set Up the SecureAuthentication object

The SecureAuthentication is a singleton object, and must be provided with context, appId and companyName before using it. This will serve as the object on which all function calls are to be made.

{% tabs %}
{% tab title="Java" %}

```java
SecureAuthentication secureAuthentication = SecureAuthentication.getInstance();

secureAuthentication.setContext(appContext);
secureAuthentication.setAppId(APP_ID);
secureAuthentication.setAppSecret(APP_SECRET);
secureAuthentication.setApplicationKeySalt(APP_SALT);
secureAuthentication.setCompanyName(companyName);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val secureAuthentication = SecureAuthentication.getInstance()

    secureAuthentication.setContext(appContext)
    secureAuthentication.setAppId(APP_ID)
    secureAuthentication.setAppSecret(APP_SECRET);
    secureAuthentication.setApplicationKeySalt(APP_SALT);
    secureAuthentication.setCompanyName(companyName)
```

{% endtab %}
{% endtabs %}

### Register a User

Use SecureAuthentication's method `signUp` to register a new user instead of relying on standard AWS Mobile SDK's signUp method.

{% tabs %}
{% tab title="Java" %}

```java
boolean registerBayunWithPwd = true;

// Hashmap to save the signup fields
HashMap signUpFields = new HashMap<String, String>();

// Read user data and register
CognitoUserAttributes userAttributes = new CognitoUserAttributes();
userAttributes.addAttribute(signUpFields.put("Email", "email@mydomain.com")

// SignupHandler to handle signup outcomes.
SignUpHandler signUpHandler = new SignUpHandler() {
    @Override
    public void onSuccess(CognitoUser user, SignUpResult signUpResult) {
        if (signUpResult.getUserConfirmed()) {
            // User is already confirmed
            // handle the case where user identity is already confirmed.
        }
        else {
            // User is not confirmed
            // handle the case where user has to confirm his identity
        }
    }

    @Override
    public void onFailure(Exception exception) {
        // Handle failure.
    }
};

// Signup call
SecureAuthentication.getInstance().signUp(activityContext, userPool, usernameInput, userpasswordInput, userAttributes, null, signUpHandler, registerBayunWithPwd);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Hashmap to save the signup fields
var signUpFields<String,String> = HashMap()

// Read user data and register
val userAttributes =  CognitoUserAttributes()
userAttributes.addAttribute(signUpFields.put("Email", "email@mydomain.com")

// SignupHandler to handle signup outcomes.
val signUpHandler: SignUpHandler = object : SignUpHandler {
        override fun onSuccess(
            user: CognitoUser, signUpConfirmationState: Boolean,
            cognitoUserCodeDeliveryDetails: CognitoUserCodeDeliveryDetails
        ) {
            // Check signUpConfirmationState to see if the user is already confirmed
            if (signUpConfirmationState) {
                // User is already confirmed
                // handle the case where user identity is already confirmed.
            }
            else {
                // User is not confirmed
                // handle the case where user has to confirm his identity
            }
        }

        override fun onFailure(exception: Exception) {
            // Handle failure.
        }
}

// Signup call
SecureAuthentication.getInstance().signUp(activityContext, userPool, usernameInput, userpasswordInput, userAttributes, null, signUpHandler, registerBayunWithPwd)

```

{% endtab %}
{% endtabs %}

### Confirm Signup

Confirm a users' sign up with the confirmation code using SecureAuthentication's `confirmSignUp` method. Use this method instead of `CognitoUser`'s method, to confirm signup with both Cognito and Bayun.

{% tabs %}
{% tab title="Java" %}

```java
// Callback to handle the confirmation api call.
GenericHandler confHandler = new GenericHandler() {
    @Override
    public void onSuccess() {
        Log.d(TAG, "User confirmed.");
        // Handle success.
    }

    @Override
    public void onFailure(Exception exception) {
        // Handle failure.
    }
};

// Call to confirm the user.
SecureAuthentication.getInstance().confirmSignUp(activityContext, cognitoUser, confirmCode, forcedAliasCreation, confHandler);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Callback to handle the confirmation api call.
 val confHandler: GenericHandler = object : GenericHandler {
                override fun onSuccess() {
                    // Handle success.
                }

                override fun onFailure(exception: java.lang.Exception) {
                    // Handle failure.
                }
}

// Call to confirm the user.
SecureAuthentication.getInstance().confirmSignUp(context, cognitoUser, confirmCode, forcedAliasCreation, confHandler)

```

{% endtab %}
{% endtabs %}

### Sign in a user

Use SecureAuthentication's `signIn` method to get a session, using username and password, with both Cognito and Bayun, instead of `CognitoUser`'s method.

{% tabs %}
{% tab title="Java" %}

```java
// Callback to handle the signIn api call.
AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
    @Override
    public void onSuccess(CognitoUserSession cognitoUserSession, CognitoDevice device) {
    Log.d(TAG, "User sign in success.");
        // Handle success.
        // This block is also executed when a user is already signed in.
    }

    @Override
    public void getAuthenticationDetails(AuthenticationContinuation continuation, String username) {
        AuthenticationDetails authenticationDetails = new AuthenticationDetails(username, password, validationData);
        continuation.setAuthenticationDetails(authenticationDetails);
        continuation.continueTask();
    }

    @Override
    public void getMFACode(MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation) {
        // Handle this block, if needed.
    }

    @Override
    public void onFailure(Exception e) {
        // Handle failure.
    }

    @Override
    public void authenticationChallenge(ChallengeContinuation continuation) {
        /**
         * For Custom authentication challenge, implement your logic to present challenge to the
         * user and pass the user's responses to the continuation.
         */
    }
};

// Call to sign in a user.
SecureAuthentication.getInstance().signIn(activityContext, username, password, cognitoUser, authenticationHandler);

```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Callback to handle the signIn api call.
val authenticationHandler: AuthenticationHandler = object : AuthenticationHandler {
            override fun onSuccess(cognitoUserSession: CognitoUserSession, device: CognitoDevice) {
                Log.d(TAG, "User sign in success.")
                // Handle success.
                // This block is also executed when a user is already signed in.

            }

            override fun getAuthenticationDetails(
                continuation: AuthenticationContinuation,
                username: String
            ) {
                val authenticationDetails =
                    AuthenticationDetails(username, password, validationData)
                continuation.setAuthenticationDetails(authenticationDetails)
                continuation.continueTask()
            }

            override fun getMFACode(multiFactorAuthenticationContinuation: MultiFactorAuthenticationContinuation) {
                // Handle this block, if needed
            }
            override fun onFailure(e: java.lang.Exception) {
                // Handle failure.
            }

            override fun authenticationChallenge(continuation: ChallengeContinuation) {
                /**
                 * For Custom authentication challenge, implement your logic to present challenge to the
                 * user and pass the user's responses to the continuation.
                 */
            }
}
// Call to sign in a user.
SecureAuthentication.getInstance().signIn(activityContext, username, password, cognitoUser, authenticationHandler);

```

{% endtab %}
{% endtabs %}

### Sign out a user

Use SecureAuthentication's `signOut` method to clear all tokens and logout of Bayun as well, instead of using `CognitoUser`'s method. User will have to go through the authentication process to get tokens.

{% tabs %}
{% tab title="Java" %}

```java
SecureAuthentication.getInstance().signOut(cognitoUser);
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bayun.gitbook.io/bayun-awss3-wrapper-android-programming-guide/authenticating_with_bayun/42-authenticate-using-aws-cognito-service-wrapper/4.2.2-using-user-pools-with-bayun-awss3-wrapper-secureauthentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
