Facebook OAuth: Callback URI gives me an HTTP ERROR 500 - asp.net

So I am pretty much using the default MVC-template that includes OAuth authentication with facebook. But after authenticating I am getting an HTTP ERROR 500.
I am using OAuth Version 4.0. My ConfigureAuth looks like this:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Local Login Cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/ExternalLogin"),
ExpireTimeSpan = TimeSpan.FromDays(3),
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Facebook
var facebookOptions = new FacebookAuthenticationOptions
{
AppId = "[MY APP ID]",
AppSecret = "[MY APP SECRET]",
CallbackPath = new PathString("/Account/ExternalLoginCallback"),
};
app.UseFacebookAuthentication(facebookOptions);
}
In my facebook app I have added https://localhost:44365/Account/ExternalLoginCallback to my valid OAuth Redirect URIs.
I have searched for an answer but couldnt find anything. What am I missing?

As of March 2018 Strict mode is enabled by default.
Add the following callback URIs in your facebook App settings:
http://localhost:44365/
http://localhost:44365/ExternalLoginCallback
http://localhost:44365/signin-facebook

Related

User unauthorized after Azure AD login to different application simultaneously

I have two MVC applications AppA and AppB, and implemented Azure AD authentication for login.
I am able to sign-in successfully to both applications.
But the issue is, after I login to AppA and then to AppB, after sometime when I return back to AppA I am facing the issue where user has been logged out, and it again redirects to login screen (in AppA).
After I login to AppA (second time) and go back to AppB (user in AppB is logged out).
Client IDs are different ; TenandID is same. Both apps are hosted in same server.
Startup file:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SlidingExpiration = true,
Provider = new CookieAuthenticationProvider
{
OnResponseSignIn = context =>
{
context.Properties.AllowRefresh = true;
context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1);
},
OnValidateIdentity = MyCookieValidateIdentity
},
ExpireTimeSpan = TimeSpan.FromDays(2)
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = appId,
//CookieManager=new SameSiteCookieManager(new SystemWebCookieManager()),
Authority = "https://login.microsoftonline.com/xxxxxx/v2.0",
Scope = $"openid email profile offline_access {graphScopes}",
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = (context) =>
{
context.ProtocolMessage.DomainHint = "xyz.com";
return Task.FromResult(0);
},
// SecurityTokenValidated = OnSecurityTokenValidated,
AuthenticationFailed = OnAuthenticationFailedAsync,
AuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync
}
}
);
}
actionContext.RequestContext.Principal.Identity.IsAuthenticated is returning False
I am assuming it has to do something with the cookie. Can someone please help resolve this ?
Edit:
Debugged further and found:
Initially if the cookies for AppA are set as:
.AspNet.Cookies = A_abc123 ; ASP.NET_SessionId = A_def456
And for AppB .AspNet.Cookies = B_mno123 ; ASP.NET_SessionId = B_pqr456
Then after I click any link in AppA, the cookie's values are updated with AppB's cookies, i.e. .AspNet.Cookies = B_mno123 ; ASP.NET_SessionId = B_pqr456
.AspNet.Cookies ASP.NET_SessionId
AppA A_abc123 A_def456
AppB B_mno123 B_pqr456
AppA B_mno123 B_pqr456
One thing that you need to do is to configure the Data Protection API so that both services uses the same cookie protection key. Out of the box each service creates its own unique key, and a cookie from one service is not valid in a different service.
I also did a blog post about the data protection API here.
See
How to: Use Data Protection
Get started with the Data Protection APIs in ASP.NET Core
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
//AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,// DefaultAuthenticationTypes.ApplicationCookie,
CookieName = ".AspNet.AppA.Cookies",
SlidingExpiration = true,
CookieManager = new SystemWebCookieManager(),
Provider = new CookieAuthenticationProvider
{
OnResponseSignIn = context =>
{
context.Properties.AllowRefresh = true;
context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1);
},
},
ExpireTimeSpan = TimeSpan.FromDays(2)
});
//... code removed for brevity //
}
The Default Cookie Name set by the application was: .AspNet.Cookies
And when I modified the default cookie name, the issue got resolved. Each application was generating its own cookiename and hence the other application was not signing out the user.

Modify Startup.cs code from Core to legacy ASP.NET

I want to modify a legacy ASP.NET WebForms application to use Azure SAML authentication. I found SAML authentication sample for ASP.NET Core on Microsoft site and want to modify this code to fit in my Web Forms application Startup class.
The below code I want to change:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = "Saml2";
})
.AddSaml2(options =>
{
options.SPOptions.EntityId = new EntityId("https://localhost:44342/Saml2");
options.IdentityProviders.Add(
new IdentityProvider(
new EntityId("https://sts.windows.net/63eb1bcb-f74f-4703-8243-6f73d78ebf52/"), options.SPOptions)
{
MetadataLocation = "https://login.microsoftonline.com/63eb1bcb-f74f-4703-8243-6f73d78ebf52/federationmetadata/2007-06/federationmetadata.xml?appid=9fd05134-d507-479b-a432-580541125356"
});
})
.AddCookie();
This code uses 'services' which is not available in my startup class. My existing code looks like this:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
//interactive logon process
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
//name of the authentication type
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
//Login path should be below
// LoginPath = new PathString("login"),
//TODO: Enable this to always send and receive cookies in SSL when in production
CookieSecure = CookieSecureOption.Always,
//enable sliding expiration
SlidingExpiration = true,
//Cookie expires in 4 hours
ExpireTimeSpan = TimeSpan.FromTicks(DateTime.Now.AddHours(4).Ticks)
});
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
{
MetadataAddress = adfsMetadata,
Wtrealm = realm
});
//This will set ADFS as the default authentication provider
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseStageMarker(PipelineStage.Authenticate);
}
Update
Below article should be easy than previous. You can refer it.
Code Your C#/ASP.NET App to Provide SSO via OneLogin
sample code : https://github.com/onelogin/dotnet-saml
Previous
You can refer this doc learn how to fit your Web Forms application in Startup.Auth.cs class.
Official doc :
Sustainsys.Saml2 --ASP.NET Web Forms
You also can refer this code.
SampleOwinApplication

Protocol to implement Azure AD

I have a legacy ASP.NET Web Forms application. It is at present using on-prem ADFS with Cookie Authentication and WSFederation protocol.
We want to move it to Azure AD. I want to know whether I need to change WSFederation protocol or it too works with Azure AD. Also, is it required to change Cookie Authentication?
Code from Startup.CS is as below:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
//interactive logon process
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
//name of the authentication type
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
//TODO: Enable this to always send and receive cookies in SSL when in production
CookieSecure = CookieSecureOption.Always,
//enable sliding expiration
SlidingExpiration = true,
//Cookie expires in 4 hours
ExpireTimeSpan = TimeSpan.FromTicks(DateTime.Now.AddHours(4).Ticks)
});
app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
{
MetadataAddress = adfsMetadata,
Wtrealm = realm
});
Edited *
Code modified as below:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
//interactive logon process
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
//name of the authentication type
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
//Login path should be below
// LoginPath = new PathString("login"),
//TODO: Enable this to always send and receive cookies in SSL when in production
CookieSecure = CookieSecureOption.Always,
//enable sliding expiration
SlidingExpiration = true,
//Cookie expires in 4 hours
ExpireTimeSpan = TimeSpan.FromTicks(DateTime.Now.AddHours(4).Ticks)
});
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
app.UseWindowsAzureActiveDirectoryBearerAuthentication(new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
MetadataAddress = AzureMetaData,
Tenant = Tenant,
Realm = Realm
});
Now it is throwing error:
System.ArgumentNullException: 'Value cannot be null. Parameter name:
allowedAudience'
Yes, Azure AD supports WS-Fed. Ref: Integrating a web app with Azure AD using WS-Federation
For allowedAudiences, the value of this field has to match what is in the "audience" field of the token that is being sent to your service. You can go to the Azure AD app registration for your service and look in the manifest at the "identifierUris" field. The value here should match the value that you put in the Allowed Token Audiences list.
You can also go to https://resources.azure.com/ > drill down into the App Service resource > config > authsettings and correct allowedAudiences value:
"allowedAudiences":[
"https://mysite.azurewebsites.net"
]

ASP.Net MVC application azure active directory Authentication issue "we couldnt signin you, please try again later"

I have implemented Azure Active Directory authentication in my asp.net web app.
startup.auth.cs
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = redirectUri,
RedirectUri = redirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
//
// If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
//
AuthorizationCodeReceived = OnAuthorizationCodeReceived,
AuthenticationFailed = OnAuthenticationFailed
}
});
}
when i hit application url , its going to AD authentication, when i enter my credentials after completing two factor authentication it keeps trying to connect and finally says "we couldnt signin you, please try again later". please help
Authentication issue
its single page application created in asp.net mvc with type script.
please help me to resolve this issue. thanks!!!
(Moving from Comments to answer)
The above issue is resolved by following in the Document and GitHub Sample.

If Authorize fail in Web-api (asp.net) , browser show basic authentication

I just want to get Error Message.
But application show It needs basic login.
How can I pass it?
AccountServiceController
[Authorize]
[Route("UserRoles")]
public async Task<IHttpActionResult> GetUserRoles(string userName){
//my code
}
Strat.Auth
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
ExpireTimeSpan = System.TimeSpan.FromDays(1)
});
var OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/Token"),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
Provider = new DrDB.Identity.Infrastructure.SimpleAuthorizationServerProvider()
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
You're going about this the wrong way.
The WebAPI shouldn't be displaying the logon prompt - the calling application should.
If you check the response that the WebAPI is returning, it's likely a 401 (unauthorized).
The caller can check for a 401 response, and display whatever login page it needs to.

Resources