how to fix 403 error in google authentication at xamarin forms for accessing web resources at Android app - xamarin.forms

thanks in advance.....
i got this error while connecting to my app with azure cloud via google authentication
"403. that's an error. error: disallowed _useragent this user- agent is not permitted to make on oauth authorization request to google as it is calssified as an embedded user- agent per our policy ,only browsers are permitted to make authorization request to google. we offer several libraries and samples for native apps to perform authorization request in the browser."
how to fix this error.....

This happens from last year because of a change in Google's security policy. The work around is to use Xamarin.Auth and use Interceptors in the native codes to catch the Authentication process. A good example is available in this following link Xamarin Authentication
class ActivityCustomUrlSchemeInterceptor : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
/* global::Android.Net.Uri uri_android = Intent.Data;
//#if DEBUG
// System.Text.StringBuilder sb = new System.Text.StringBuilder();
// sb.AppendLine("ActivityCustomUrlSchemeInterceptor.OnCreate()");
// sb.Append(" uri_android = ").AppendLine(uri_android.ToString());
// System.Diagnostics.Debug.WriteLine(sb.ToString());
//#endif
// Convert iOS NSUrl to C#/netxf/BCL System.Uri - common API
Uri uri_netfx = new Uri(uri_android.ToString());
// load redirect_url Page
AuthenticationState.Authenticator.OnPageLoading(uri_netfx);*/
var uri = new Uri(Intent.Data.ToString());
// Load redirectUrl page
AuthenticationState.Authenticator.OnPageLoading(uri);
this.Finish();
return;
}
}

Related

Google Authentication Asp.net Core

I'm getting the below error when I try to login using Google on my web app.
It works fine when using localhost
This pelusoftcamerawebapp.azurewebsites.net page can’t be found No web
page was found for the web address:
https://pelusoftcamerawebapp.azurewebsites.net/signin-google?state=CfDJ8BRnSyuVZrdLjm6frrOu1DBgXqvK5dey3eI632SEKrS7vg........
goole login code:
[HttpGet]
[Route("google-login")]
public IActionResult GoogleLogin(string returnUrl = null)
{
var authProperties = new Microsoft.AspNetCore.Authentication.AuthenticationProperties
{
RedirectUri = string.IsNullOrEmpty(returnUrl) ? "account/profile" : returnUrl,
IsPersistent = true
};
return Challenge(authProperties, new string[] { "google" });
}
I have added pelusoftcamerawebapp.azurewebsites.net to the google console domain verification
do you have any idea?
Since Google has shutdown Google Plus so Google Plus based authentication mechanism has been changed and it has also effected the existing Google authentication in ASP.NET and ASP.NET Core.
Microsoft has updated the Google authentication library for both ASP.NET and ASP.NET Core.
Here is the more details: Google+ based auth deprecation and replacement

Issue with jwt-bearer on-behalf-of grant in Azure AD

So I have an Angular app that uses the adal-angular library to authenticate with an ASP.NET Core 2.0 Web API. The API then uses on-behalf-of flow to authenticate with another API using the users token like this MS article https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-on-behalf-of.
The issue I have is this is working fine in the DEV environment but I have now deployed a TST environment with separate App Registrations and I am receiving the following exception when I try and request the token using on-behalf-of
AADSTS240002: Input id_token cannot be used as 'urn:ietf:params:oauth:grant-type:jwt-bearer' grant.
The code I am using to request the token
public async Task<string> AcquireTokenAsync(string resource)
{
try
{
string accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync(AuthenticationConstants.AccessToken);
var credentials = new ClientCredential(_azureOptions.ClientId, _azureOptions.ClientSecret);
var authContext = new AuthenticationContext($"{_azureOptions.Instance}{_azureOptions.TenantId}")
{
ExtendedLifeTimeEnabled = true
};
// On-behalf-of auth token request call
var authResult = await authContext.AcquireTokenAsync(
resource,
credentials,
new UserAssertion(accessToken));
return authResult.AccessToken;
}
catch (AdalServiceException asex)
{
_logger.LogError(asex, $"Instance: {_azureOptions.Instance} Tenant: {_azureOptions.TenantId} ClientId: {_azureOptions.ClientId}");
throw;
}
catch (System.Exception ex)
{
_logger.LogError(ex, ex.Message);
throw;
}
}
And I have used Fiddler and it looks like all the correct parameters are being passed.
Any help would be very much appreciated. I have set knownClientApplications on the second API and I have granted permissions on the Angular backend API to the second API.
For me, I got it to work by changing BOTH of the following to true:
oauth2AllowImplicitFlow
oauth2AllowIdTokenImplicitFlow
See here for more information.
According to your question and the error, it should be caused by that you angular app is not a Native(public) app.
For using this OBO flow with this Grant type, your client must be a public client not credential client.
If you want to register your client as a WebApp/API, you can refer to this Implementation:
Hope this helps!
Update
According to OP's comment, he/she got it working by changing oauth2AllowImplicitFlow from false to true.
We had this problem last week with one Azure Service Registration and not another. A review found that the token didn't return an AIO being returned. It turns out that the registration had redirects with wildcards (e.g., https://*.ngrok.io) and this is incompatible with the AcquireTokenOnBehalfOf function. I'm posting this here so a future person, probably me, will find it.
I was having problems even when oauth2AllowImplicitFlow and oauth2AllowIdTokenImplicitFlow were set to true. One of my Reply URLs had a wildcard in it. When the wildcard was removed, the issue was resolved.

ASP.NET Web Forms Site - integration with multiple ADFS using OWIN KATANA

I'm configuring an old existing web forms site as a multi-tenant environment. One requirement is to be able to integrate with multiple client ADFS.
I have followed this post and have successfully implemented an MVC application supporting multiple ADFS. However I still face an issue,
that is not reproducible with the MVC app. In my web forms site, only the first ADFS provider registered succeeds. The second one always
throws SignatureVerificationFailedException after authenticating and returning back to my site (the exception happens at my side).
This is no matter whether I use app.Map(...) or app.Use(...) in the OWIN startup configuration.
I tried converting my web site to web application, but same result. I guess it is something connected with the way requests are handled in WEB FORMS, which is different than MVC.
Should I handle the middleware mapping in some different way?
What am I missing? Or this is not possible at all?...
Here is my OWIN startup configuration:
app.Properties["Microsoft.Owin.Security.Constants.DefaultSignInAsAuthenticationType"] = Config.ExternalAuthentication.Cookie;
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = Config.ExternalAuthentication.Cookie,
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive
});
string wreply = Config.ExternalAuthentication.Wreply;
string wtrealm = Config.ExternalAuthentication.Wtrealm;
List<Company> adfsCompanies = BL.GetCompaniesWithADFS();
app.Map("/Public/Login.aspx", configuration =>
{
foreach (Company company in adfsCompanies)
{
//configure middleware
var middleware = new WsFederationAuthenticationOptions()
{
MetadataAddress = company.ADFSMetadataUrl,
AuthenticationType = company.TenantName,
Caption = company.Name,
Wreply = wreply,
Wtrealm = wtrealm,
BackchannelCertificateValidator = null
};
//add to pipeline
configuration.UseWsFederationAuthentication(middleware);
}
});
Here is my challenge request:
context.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = callbackUrl },
provider);
response.StatusCode = 401;
response.End();
No matter what I do, only the first registered ADFS middleware succeeds, no matter which one. I also tried attaching the middlewares to different pipeline stages with no success.
Thanks in advance for any help!
For multiple wsfed middleware each should set a unique WsFederationAuthenticationOptions.CallbackPath, e.g. "/ws1". You'll also need to include this value in the wreply.
I'm just giving some more details to the solution suggested by #Tratcher, in order to keep the question clean and simple:
1) According to MSDN, CallbackPath if not set is calculated from Wreply;
2) after distinguishing Wreply for each provider it turned out that was not enough, because other problems appeared. Then I found (using my MVC working sample) that furthermore Wtrealm and Wreply should have the same value;
3) Setting different URLs for different providers in ASP.NET Web Forms turned out to not be so easy. Fake URLs did not work. Using URL Rewrite - also. The most straightforward solution is to use different callback page for each provider (e.g. ExternalLoginFirstADFS.aspx, ExternalLoginSecondADFS.aspx, ...). This, although working fine, is not the best, so I decided to configure a Route for each provider at Application_Start event in Global.asax like this:
void Application_Start(object sender, EventArgs e)
{
...
RegisterRoutes(System.Web.Routing.RouteTable.Routes);
}
public static void RegisterRoutes(System.Web.Routing.RouteCollection routes)
{
List<Organization> adfsCompanies = OrgElementEntity.GetCompaniesWithADFS();
foreach(Organization company in adfsCompanies)
{
routes.MapPageRoute("",
String.Format("Public/ExternalLogin{0}.aspx", company.TenantName),
"~/Public/ExternalLogin.aspx");
}
}
Furthermore, it turned out that there is no need too use app.Map(...) at OwinStartup. Just adding each middleware through app.UseWsFederationAuthentication(...) seems to be fine!

Getting Google Oauth2 Token using dotnetopenauth

I'm having an issue retreiving the OAuth2 token for google using DotNetOpenAuth 4.2.0.13024.
I've got to the point where I can successfully make the authorization request to the google endpoint https://accounts.google.com/o/oauth2/auth
When the user clicks 'OK', google then calls my callback URL as expected with the appropriate "code" query string.
However, I am unable to exchange this code for a token, as my calls keep failing with "Protocol exception was unhandled" execption and "400 Bad request" as the inner exception. This is the code I am using to exchange the token
private static AuthorizationServerDescription authServerDescription = new AuthorizationServerDescription
{
TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth")
};
static GoogleContacts()
{
Client = new WebServerClient(authServerDescription, "{my_cliend_id}", "{me_secret_key}");
}
var authorization = Client.ProcessUserAuthorization(); // <- Exception is thrown here
if (authorization != null)
{
Authorization = authorization;
Response.Redirect(Request.Path); // get rid of the /?code= parameter
}
PS: it seems like a new version of DotNerOpenAuth has been released but, I am unable to get it because the zip download still points to the older version and Nuget keeps failing on me :(

DotNetOpenAuth Failing to work on Live Server

I worked on a sample application integrating OpenID into ASP.NET Web Forms. It works fine when hosted locally on my machine. However, when I uploaded the application to a live server, it started giving "Login Failed".
You can try a sample here: http://samples.bhaidar.net/openidsso
Any ideas?
Here is the source code that fails to process the OpenID response:
private void HandleOpenIdProviderResponse()
{
// Define a new instance of OpenIdRelyingParty class
using (var openid = new OpenIdRelyingParty())
{
// Get authentication response from OpenId Provider Create IAuthenticationResponse instance to be used
// to retreive the response from OP
var response = openid.GetResponse();
// No authentication request was sent
if (response == null) return;
switch (response.Status)
{
// If user was authenticated
case AuthenticationStatus.Authenticated:
// This is where you would look for any OpenID extension responses included
// in the authentication assertion.
var fetchResponse = response.GetExtension<FetchResponse>();
// Store the "Queried Fields"
Session["FetchResponse"] = fetchResponse;
// Use FormsAuthentication to tell ASP.NET that the user is now logged in,
// with the OpenID Claimed Identifier as their username.
FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, false);
break;
// User has cancelled the OpenID Dance
case AuthenticationStatus.Canceled:
this.loginCanceledLabel.Visible = true;
break;
// Authentication failed
case AuthenticationStatus.Failed:
this.loginFailedLabel.Visible = true;
break;
}
}
As Andrew suggested, check the exception. In my case, my production server's time & date were off and it wouldn't authenticate because the ticket expired.
Turn on logging on your live server and inspect them for additional diagnostics. It's most likely a firewall or permissions problem on your server that prevents outbound HTTP requests.
You may also find it useful to look at the IAuthenticationResponse.Exception property when an authentication fails for clues.

Resources