Base solution for your next web application

Activities of "kansoftware"

Hi kansoftware

ExternalAuthenticationProvider structure in MVC is different from Angular. The GetExternalAuthenticationProvidersmethod in TokenAuthController is used in Angular. In MVC, ExternalAuthConfiguration *WebMvcModule.cs must also be configured. Configuration example: You can configure it according to your scenario by using the ConfigureExternalAuthProviders method in the *WebHostModule.cs class in the *.Host project. Or if you want to use it as Scheme, you can use the GetExternalAuthenticationSchemesAsync method in the SignInManager class in the *.Core project.

Hi I am reframing my question, I want to give the below API to my mobile app team to pass the okta provider code and get the access token of my application. So I found one function is already built in in token auth controller i.e. ExternalAuthenticate. I have configured okta for a tenant using openid from its settings page. Now when I am calling this API it gives me Unknown external auth provider error.

public async Task<ExternalAuthenticateResultModel> ExternalAuthenticate( [FromBody] ExternalAuthenticateModel model) {
var externalUser = await GetExternalUserInfo(model);

var loginResult = await _logInManager.LoginAsync(
    new UserLoginInfo(model.AuthProvider, externalUser.ProviderKey, model.AuthProvider),
    GetTenancyNameOrNull()
);

switch (loginResult.Result)
{
    case AbpLoginResultType.Success:
    {
        // One Concurrent Login 
        if (AllowOneConcurrentLoginPerUser())
        {
            await ResetSecurityStampForLoginResult(loginResult);
        }

        var refreshToken = CreateRefreshToken(
            await CreateJwtClaims(
                loginResult.Identity,
                loginResult.User,
                tokenType: TokenType.RefreshToken
            )
        );

        var accessToken = CreateAccessToken(
            await CreateJwtClaims(
                loginResult.Identity,
                loginResult.User,
                refreshTokenKey: refreshToken.key
            )
        );

        var returnUrl = model.ReturnUrl;

        if (model.SingleSignIn.HasValue && model.SingleSignIn.Value &&
            loginResult.Result == AbpLoginResultType.Success)
        {
            loginResult.User.SetSignInToken();
            returnUrl = AddSingleSignInParametersToReturnUrl(
                model.ReturnUrl,
                loginResult.User.SignInToken,
                loginResult.User.Id,
                loginResult.User.TenantId
            );
        }

        return new ExternalAuthenticateResultModel
        {
            AccessToken = accessToken,
            EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
            ExpireInSeconds = (int) _configuration.AccessTokenExpiration.TotalSeconds,
            ReturnUrl = returnUrl,
            RefreshToken = refreshToken.token,
            RefreshTokenExpireInSeconds = (int) _configuration.RefreshTokenExpiration.TotalSeconds
        };
    }
    case AbpLoginResultType.UnknownExternalLogin:
    {
        var newUser = await RegisterExternalUserAsync(externalUser);
        if (!newUser.IsActive)
        {
            return new ExternalAuthenticateResultModel
            {
                WaitingForActivation = true
            };
        }

        //Try to login again with newly registered user!
        loginResult = await _logInManager.LoginAsync(
            new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider),
            GetTenancyNameOrNull()
        );

        if (loginResult.Result != AbpLoginResultType.Success)
        {
            throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
                loginResult.Result,
                externalUser.EmailAddress,
                GetTenancyNameOrNull()
            );
        }

        var refreshToken = CreateRefreshToken(await CreateJwtClaims(loginResult.Identity,
            loginResult.User, tokenType: TokenType.RefreshToken)
        );

        var accessToken = CreateAccessToken(await CreateJwtClaims(loginResult.Identity,
            loginResult.User, refreshTokenKey: refreshToken.key));

        return new ExternalAuthenticateResultModel
        {
            AccessToken = accessToken,
            EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
            ExpireInSeconds = (int) _configuration.AccessTokenExpiration.TotalSeconds,
            RefreshToken = refreshToken.token,
            RefreshTokenExpireInSeconds = (int) _configuration.RefreshTokenExpiration.TotalSeconds
        };
    }
    default:
    {
        throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
            loginResult.Result,
            externalUser.EmailAddress,
            GetTenancyNameOrNull()
        );
    }
}

}

Hi kansoftware

To enable both Okta and Auth0 for a single tenant in your multi-tenant application, you will need to customize the code, as the standard ASP.NET Zero implementation typically supports only one OpenID Connect provider per tenant.

Ok. For now I have enabled okta through oidc. I have added the default options in startup.cs. But also I have configured the openid for a tenant through tenant settings page. I want to know how and where does it replaces the client id and other details before redirecting to okta login page.

As for my custom code I want to set the credentials runtime because for each tenant it will be different. I hope I am making sense

Hi @kansoftware

Where are you using the GetExternalAuthenticationProviders method? When I call the default GetExternalAuthenticationProviders method in the TokenAuthController under *Web.Core, data is returned as shown in the screenshot below. You may want to check the OpenId settings in appsettings.json again. Could you provide more details so I can reproduce this issue?

Right now I am calling through postman. Below is the curl curl --location 'https://localhost:44302/api/TokenAuth/GetExternalAuthenticationProviders'
--header 'abp.tenantid: 2'

Below is my appsettings for authentication block "Authentication": { "AllowSocialLoginSettingsPerTenant": true, "Facebook": { "IsEnabled": "false", "AppId": "", "AppSecret": "" }, "Google": { "IsEnabled": "false", "ClientId": "", "ClientSecret": "", "UserInfoEndpoint": "https://www.googleapis.com/oauth2/v2/userinfo" }, "Twitter": { "IsEnabled": "false", "ConsumerKey": "", "ConsumerSecret": "" }, "Microsoft": { "IsEnabled": "false", "ConsumerKey": "", "ConsumerSecret": "" }, "WsFederation": { "IsEnabled": "false", "MetaDataAddress": "", "Wtrealm": "" }, "JwtBearer": { "IsEnabled": "true", "SecurityKey": "", "Issuer": "CDP", "Audience": "CDP" }, "OpenId": { "IsEnabled": "true", "Authority": "https://fynauth0.uk.auth0.com", "ClientId": "", "ClientSecret": "***", "ValidateIssuer": "false", "ResponseType": "code", "ClaimsMapping": [ { "claim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "key": "http://schemas.microsoft.com/identity/claims/objectidentifier" } ] } }

Also I have set openid for tenant id 2 from it's settings page as I have multi tenant application. Could you please let me know if I have missed out something. Also what changes you have made to enable openid

@huntethan89 Were you able to find a solution for this?

@ismcagdas I am too facing the similar error. I have enable OpenId in appsettings.json and also configured for a tenant. But I am too getting the same error

Answer

Any Update on it??

Hi @kansoftware

Could you test with a tool or redis-cli to see if you are able to connect to your redis instance ?

Yes, we can connect to the Redis server using telnet, but we are unable to establish a connection in our application

Thanks

But Redis not getting connect.

Currently we have hosted application on linux server which is behind load balancer and in case enable scaling and multiple instances are running. Chat module is not working.

I believe we need to configure backplane looking at documentation

Do you have steps configuration we are using latest version of aspnetzero.

We are facing similar issue

while we enabled cache

We are getting following error RedisConnectionException: It was not possible to connect to the redis server(s). Error connecting right now. To allow this multiplexer to continue retrying until it's able to connect, use abortConnect=false in your connection string or AbortOnConnectFail=false; in your code. Telnet is also working

Regards,

Actually we are running both versions on the server but we only see these waits for the new application

Can you please check why the newer version introduce the waits.

its happening on production so request you for a quick response

Regards

Hi @kansoftware

In the tenant settings page, a tenant can load a custom logo and css file. You can add two more items to this section and save them as we do for custom logo and css.

Then, you can use these two info in Layout page.

Thanks for quick response. Its done as you suggested.

Showing 11 to 20 of 101 entries