Base solution for your next web application

Activities of "omkarchoudhari"

Hello, Is there any update on this Please ?

@ismcagdas,

Any update on this? We are chasing a completion here and it depends on resolving this issue.

@ismcagdas,

Sorry for the late response, but requesting you to treat this as URGENT :)

Yes, we have tested it on the nonmodified template as well. it is giving me the same error.

Could one of the following reasons be the possibility of this error?

  1. Behaviours folder missing from Mobile.Shared (we are using MVC Core, Jquery but to check, we checked what folder we see in the shared folder of documentation).

  2. Template is using "using MvvmHelpers".

(Maybe try to use "using Xamarin.CommunityToolkit.ObjectModel" instead of "using MvvmHelpers") as the error is related to community toolkit.

Thanks

@ismcagdas Any update on this ?

@ismcagdas,

Sorry for the late response, but requesting you to treat this as URGENT :)

Yes, we have tested it on the nonmodified template as well. it is giving me the same error.

Could one of the following reasons be the possibility of this error?

  1. Behaviours folder missing from Mobile.Shared (we are using MVC Core, Jquery but to check, we checked what folder we see in the shared folder of documentation).

  2. Template is using "using MvvmHelpers".

(Maybe try to use "using Xamarin.CommunityToolkit.ObjectModel" instead of "using MvvmHelpers") as the error is related to community toolkit.

Thanks

Hello,

I am using MVC Jquery Template (Version 12.0.0) with .Net (version 7) and Xamarin for Android & iOS. This is a single Tenant application - only with Default Tenant.

My query is,

  1. In iOS real device(iPhone 14 and Iphone13) when I am trying to run my application in debug mode (in release mode as well), I am getting the following error;

"InnerException {Xamarin.Forms.Xaml.XamlParseException: Position 162:10. Type xct:EventToCommandBehavior not found in xmlns http://xamarin.com/schemas/2020/toolkit at Xamarin.Forms.Xaml.CreateValuesVisitor.Visit (Xamarin.Forms.Xaml.ElementNode node, Xamarin.Forms.Xaml.INode …} Xamarin.Forms.Xaml.XamlParseException"

But it is working in an iOS emulator, the only problem is with a real device. Is there any solution for the same? I need the help ASAP.

**Notes: **

  1. Added device UDID in Developer Account and uploaded Provision Certificate in iOS project
  2. Xamarin.Forms -5.0.0.2578
  3. Xamarin.Essentials-1.7.6
  4. Xamarin.CommunityToolkit - 2.0.6

Code Snippets:

  1. In LoginView.Xaml <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Name="LoginPage" xmlns:xct="http://xamarin.com/schemas/2020/toolkit" x:Class="IMS.Views.LoginView" BackgroundColor="{StaticResource LoginBackgroundColor}" base:ViewManager.AutoWireViewModel="true" Title="{extensions:Translate LogIn}"> . . . . <ContentPage.Behaviors> <xct:EventToCommandBehavior EventName="Appearing" Command="{Binding PageAppearingCommand}" /> </ContentPage.Behaviors> </contentPage>

  2. In LoginViewModel:

    public class LoginViewModel : XamarinViewModel { Default code of ASPNET Zero . . .

    //My Code public ICommand RegisterUserCommand => HttpRequestCommand.Create(Method for Register); public ICommand RegisterGoogleCommand => HttpRequestCommand.Create(Method for Google); public ICommand RegisterMicrosoftCommand => HttpRequestCommand.Create(Method for Microsoft);

    Default code of ASPNET Zero . . .

     private readonly IPublicClientApplication PCA;
     private readonly IGoogleClientManager _googleClientManager;
     public string Token { get; set; }
    

    Default code of ASPNET Zero . . .

     public LoginViewModel(
         IAccountAppService accountAppService,
         IApplicationContext applicationContext,
         IAccountService accountService,
         IDataStorageService dataStorageService)
     {
     .
     .
     .
    
         _googleClientManager = CrossGoogleClient.Current;
         var myUri = new Uri(ApplicationSetting.TenantUrl, UriKind.Absolute);
         PCA = PublicClientApplicationBuilder.Create(ApplicationSetting.ClientID)
                 .WithIosKeychainSecurityGroup(ApplicationSetting.ApplicationId)
                 .WithAuthority(myUri)
                 .WithRedirectUri(ApplicationSetting.RedirectUrl)
                 .Build();
     }
    

    Default code of ASPNET Zero . .

     private async Task PageAppearingAsync()
     {
         PopulateLoginInfoFromStorage();
         await Task.CompletedTask;
     }
    

    Default code of ASPNET Zero . . .

     //My Code
     //#1. Microsoft Login
     public async Task MicrosoftRegistrationCallerAsync()
     {
         try
         {
         	try
         	{
             	var authResult = await PCA.AcquireTokenInteractive(ApplicationSetting.Scopes)
                     	        .WithParentActivityOrWindow(App.ParentWindow)
                             	.WithUseEmbeddedWebView(true)
                             	.ExecuteAsync();
    
             	//#1. External Authentication Model
             	_accountService.CustomExternalAuthenticateModel.ProviderKey = authResult.UniqueId;
             	_accountService.CustomExternalAuthenticateModel.ProviderAccessCode = authResult.AccessToken;
             	_accountService.CustomExternalAuthenticateModel.AuthProvider = "Microsoft";
    
             	await SetBusyAsync(async () =>
             	{
                 		await _accountService.LoginUserExternalAsync();
             	});
         	}
         	catch (Exception ex)
         	{
             	await Application.Current.MainPage.DisplayAlert("Alert", "Invalid Login Credentials, please try again.", "Ok");
             	Console.WriteLine(ex.Message);
         	}
     }
    
     //#1. Google Login
     private async Task RegisterGoogleAsync()
     {
         _googleClientManager.OnLogin += OnLoginCompleted;
         try
         {
             await _googleClientManager.LoginAsync();
         }
         catch (Exception ex)
         {
             await App.Current.MainPage.DisplayAlert("Error", ex.Message, "OK");
         }
     }
    
     //#2. Google Login
     private void OnLoginCompleted(object sender, GoogleClientResultEventArgs&lt;GoogleUser&gt; loginEventArgs)
     {
         if (loginEventArgs.Data != null)
         {
             GoogleUser googleUser = loginEventArgs.Data;
             Token = CrossGoogleClient.Current.AccessToken;
    
             //#1. External Authentication Model
             _accountService.CustomExternalAuthenticateModel.ProviderKey = googleUser.Id.ToString();
             _accountService.CustomExternalAuthenticateModel.ProviderAccessCode = Token;
             _accountService.CustomExternalAuthenticateModel.AuthProvider = "Google";
    
             SetBusyAsync(async () =>
             {
                 await _accountService.LoginUserExternalAsync();
             });
         }
         else
         {
             App.Current.MainPage.DisplayAlert("Error", loginEventArgs.Message, "OK");
         }
    
         _googleClientManager.OnLogin -= OnLoginCompleted;
    
     }
    
     //#3. Google Logout
     public void Logout()
     {
         _googleClientManager.OnLogout += OnLogoutCompleted;
         _googleClientManager.Logout();
     }
    
     //#4. Google Logout
     private void OnLogoutCompleted(object sender, EventArgs loginEventArgs)
     {
         _googleClientManager.OnLogout -= OnLogoutCompleted;
     }
    

Thank you in advance !

Hello @ismcagdas,

This issue is now resolved.

What did we do to resolve this issue ?

  1. If we are using Microsoft and Google Login (on the web). Then we will already have consumer secrets, secret Id, etc. configurations in our MVC. Just copy them and paste them into Web.Host project's appsettings.

  2. Auth Provider for Microsoft will be Microsoft, for Google will be Google, etc. (Please provide Hard coded values for Auth providers)

  3. when you run the project and receive auth token, values will be set to particular properties (from the custom model- create CustomExternalAuthenticateModel just like ExternalAuthenticateModel in TokenAuthController , and also create CustomExternalAuthenticateResultModel just like ExternalAuthenticateResultModel in TokenAuthController Create these files in Application.Client project) and it sends a request to the ExternalAuthenticate method.

  4. And rest is done by ANZ itself (it takes us to the main page - the flyout page).

Note: Just follow the normal Login flow and create the required models, classes, etc. To run project locally, run two VS instances. On one VS instance run Droid project and on the other run Web.Host (not IIS server profile, run Mobile) in other VS.

Hope this is helpful to someone who faces similar issue.

Thanks for your support

Hello ,

I am using MVC Jquery Template (Version 12.0.0) and Xamarin for Android. I have a Microsoft login button on the Android app (registered in Azure). This is a single Tenant application - only with Default Tenant. When I click on it:

  1. it takes me to the Microsoft login page (code written in LoginViewModel.cs)

  2. I log in with my company credentials and get redirected back to my app.

  3. Then I set the values for my model and then a method gets called (_accountService.LoginUserMicrosoftAsync).

     var myUri = new Uri(ApplicationSetting.TenantUrl, UriKind.Absolute);
     PCA = PublicClientApplicationBuilder.Create(ApplicationSetting.ClientID)
             .WithIosKeychainSecurityGroup(ApplicationSetting.TenantId)
             .WithAuthority(myUri)
             .WithRedirectUri(ApplicationSetting.RedirectUrl)
             .Build();
    
     private async Task RegisterMicrosoftAsync()
     {
         try
         {
             var authResult = await PCA.AcquireTokenInteractive(ApplicationSetting.Scopes)
                             .WithParentActivityOrWindow(App.ParentWindow)
                             .WithUseEmbeddedWebView(true)
                             .ExecuteAsync();
    
             //#1. External Authentication Model
             _accountService.CustomExternalAuthenticateModel.UserNameOrEmailAddress = authResult.Account.Username;
             _accountService.CustomExternalAuthenticateModel.ProviderKey = authResult.UniqueId;
             _accountService.CustomExternalAuthenticateModel.ProviderAccessCode = authResult.AccessToken;
    
             //Getting All Claims From Access Token
             claims = authResult.ClaimsPrincipal.Claims;
             foreach (var claim in claims)
             {
                 if (claim.Type == "iss")
                 {
                     _accountService.CustomExternalAuthenticateModel.AuthProvider = claim.Issuer;
                     break;
                 }
             }
    
             //#2. Authenticate Model
             _accountService.AbpAuthenticateModel.UserNameOrEmailAddress = authResult.Account.Username;
             _accountService.AbpAuthenticateModel.Password = "123qwe";
    
             //MessagingCenter.Send&lt;String&gt;(authResult.Account.Username, "MicrosoftMail");
    
             await SetBusyAsync(async () =>
             {
                 await _accountService.LoginUserMicrosoftAsync();
             });
         }
         catch (Exception exp)
         {
             await Application.Current.MainPage.DisplayAlert("Alert",
                 "Invalid Login Credentials, please try again.", "Ok");
             Console.WriteLine(exp.Message);
         }
     }
    
  4. (_accountService.LoginUserMicrosoftAsync) This method in turn calls a method (_accessTokenManager.LoginMicrosoftAsync).

     public async Task LoginUserMicrosoftAsync()
     {
         await WebRequestExecuter.Execute(_accessTokenManager.LoginMicrosoftAsync, ExternalAuthenticateSucceed, ex => Task.CompletedTask);
     }
    
     public async Task&lt;CustomExternalAuthenticateResultModel&gt; LoginMicrosoftAsync()
     {
         EnsureAccessTokenProvided();
    
         using (var client = CreateApiClient())
         {
             if (_externalAuthenticateModel.ProviderAccessCode != null)
             {
                 client.WithHeader(_multiTenancyConfig.TenantIdResolveKey, _applicationContext.CurrentTenant.TenantId).WithOAuthBearerToken(_externalAuthenticateModel.ProviderAccessCode);
             }
    
             var response = await client
                 .Request(LoginUrlSegmentMicrosoft) //LoginUrlSegmentMicrosoft = "api/TokenAuth/ExternalAuthenticate"
                 .PostJsonAsync(_externalAuthenticateModel) //externalAuthenticateModel model had exact properties like ExternalAuthenticateModel
                 .ReceiveJson&lt;AjaxResponse&lt;CustomExternalAuthenticateResultModel&gt;>(); //CustomExternalAuthenticateResultModel model has exact properties like ExternalAuthenticateResultModel
    
             if (!response.Success || response.Result == null)
             {
                 ExternalAuthenticateResult = null;
                 throw new UserFriendlyException(response.Error.Message + ": " + response.Error.Details);
             }
    
             ExternalAuthenticateResult = response.Result;
             ExternalAuthenticateResult.RefreshTokenExpireInSeconds = DateTime.Now.Add(AppConsts.RefreshTokenExpiration).Second;
    
             return ExternalAuthenticateResult;
         }
     }
    
  5. This method sends a request To API; in TokenAuthController (api/TokenAuth/ExternalAuthenticate).

  6. So, when this API is hit, the method, var externalUser = await GetExternalUserInfo(model) throws an exception/errors out, saying that Unknown External Auth Provider https://login.microsoftonline.com/{Tenant Id Of different organizations}/v2.0.

I tried every setting, even by setting the Auth Provider exactly the same as I am getting (in appsettings), but it didn’t work. I tried setting AuthProvider as Microsoft also, but this is not working. If I comment var externalUser = await GetExternalUserInfo(model) method, then the login works fine (as the user is already registered.). But with this method uncommented, it always checks user info and errors out. I want functionality that when a user tries to log in through different Microsoft accounts (e.g. Outlook, hotmail, etc.), and if a user doesn't exist then it should register it.

Please help urgently. Thanks in advance.

We initiate request to client to migrate the template to new version but, this may take some time. So, if you could share us the code to apply security headers both at Front end (Angular) and Backend (Asp Net Core) , we can integrate those piece of code in our current application

Hello Ismail,

We are using ASP net Zero template version "10.3.0"

As a part of Security Penetration Test, we ran the application in OWASP ZAP 2.12.0 tool. This tool give us some alerts regarding security headers and cookies.

We applied all required headers through backend ASP.NET application. Followed Link =>https://support.aspnetzero.com/QA/Questions/8144/How-to-add-a-custom-HTTP-response-header-in-AspNet-Zero All required security headers are applied to backend API application successfully. Even we applied same headers through angular web.config as well.

But when we ran the application in OWASP ZAP 2.12.0 , it is showing same header alerts We have **separate deployments for Front end and back end application. **

To ensure this, we deployed plain vanilla ASP net zero template version (10.3.0 ) to Azure. [ Separate UI and API deployment] We ran this website in OWASP ZAP 2.12.0 tool. We are receiving same alerts for this as well as like our client application.

Can you please help us to resolve UI alerts?

Please find attached screenshots for header alerts

  1. ASP net Zero plain vanilla template V(10.3.0) => ASPNetZero_Template_sceurity_Test.PNG
  2. Our application URL => ClientApp_Security_Test.PNG

In both screenshots you can see same numbers of Alerts . Can you please guide us to get rid of these security alerts.

Ismail,

I have written following code . So here I set Access token ExpireInSeconds property assigned to RefreshTokenExpiration value which is 365 days.

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

     return new AuthenticateResultModel
     {
        AccessToken = accessToken,
        ExpireInSeconds = (int)_configuration.RefreshTokenExpiration.TotalSeconds,
        RefreshToken = refreshToken.token,
        RefreshTokenExpireInSeconds = (int)_configuration.RefreshTokenExpiration.TotalSeconds,
        EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
        TwoFactorRememberClientToken = twoFactorRememberClientToken,
        UserId = loginResult.User.Id,
        TenantId = loginResult.Tenant?.Id,
        ReturnUrl = returnUrl,
     };

Looks like AbpAuthorize is not validating this access token validity . can you pl confirm.

[AbpAuthorize] public async Task<LeadOpportunityDetailDto> GetOpportunityDetail(string OpportunityId)

Showing 1 to 10 of 146 entries