Protocol to implement Azure AD - asp.net

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"
]

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

Facebook OAuth: Callback URI gives me an HTTP ERROR 500

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

How to avoid session expired cookie for Owin Federation authentication?

We are using Cookie and WsFederation middleware to authenticate against ADFS server. Everything is working fine except the generate cookie is always session expired.
When user close and reopen browser, they need to relogin.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
CookieDomain = "...some domain..."
});
app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
{
MetadataAddress = ConfigurationManager.AppSettings[AdfsMetadataAddress],
Wtrealm = ConfigurationManager.AppSettings[AppWtRealm],
UseTokenLifetime = false
});
What are the things that we need to do in order to make cookie persisted in browser side?
Thanks very much in advance~
Add a CookieAuthenticationProvider where you can set the expiration
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
CookieDomain = "...some domain...",
Provider = new CookieAuthenticationProvider
{
OnResponseSignIn = context =>
{
context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(30);
context.Properties.IsPersistent = true;
}
}
});

UseGoogleAuthentication force login session expiration?

I'm using ASP.NET MVC 5's external authentication middleware UseGoogleAuthentication/UseExternalSignInCookie with GoogleOAuth2AuthenticationOptions. Is there a way to force a user to have to re-authenticate with Google each time a user visits the site?
Presently, if the user is already logged into Google and they access the site they do not have to re-authenticate with Google. Ideally the cookie assigned would only be good for their current session on the site...
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
var authOptions = new GoogleOAuth2AuthenticationOptions();
authOptions.ClientId = AppSettingsHelper.GoogleClientId;
authOptions.ClientSecret = AppSettingsHelper.GoogleClientSecret;
authOptions.CallbackPath = new PathString("/account/linklogincallback");
foreach (var scope in AppSettingsHelper.GoogleOAuthScope)
{
authOptions.Scope.Add(scope);
}
app.UseGoogleAuthentication(authOptions);
Replace app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); with app.UseCookieAuthentication(..) and specify the ExpireTimeSpan. UseExternalSignInCookie is just a helper for the cookie authentication method that uses certain defaults.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
SlidingExpiration = true,
ExpireTimeSpan = new System.TimeSpan(0, 5, 0),
LoginPath = new PathString("/Account/Login")
});
Notice that we are using DefaultAuthenticationTypes.ExternalCookie here instead of ApplicationCookie

Resources