MVC client can't authenticate on IIS - c#

I've succeeded with IdentityServer3 implementation. I created ASP.NET MVC5 client with implicit flow and this Owin startup configuration:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{ AuthenticationType = "Cookies" });
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "mvc.client",
Authority = Constants.ServerUri,
RedirectUri = Constants.MvcClientUri,
ResponseType = "id_token",
Scope = "openid profile",
UseTokenLifetime = false,
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{ SecurityTokenValidated = TokenValidatedNotification },
});
Everything works perfect running locally on IIS Express, but fails when deployed to production IIS server. Authentication is successful in both cases - id_token is returned from then same IdentityServer, but on production user is never authenticated, notification is not fired. Project references Microsoft.Owin.Host.SystemWeb assembly. I've registered exception handling OwinMiddleware as first one, but no unhandled exception was catched.

Make sure the production IIS has the website configured to use Anonymous authentication, as you are not relying on IIS's authentication infrastructure, you want the request to flow through IIS and get to the OWIN middleware responsible for authentication.

Related

Shared cookie authentication not authenticating on server

When deploying two applications (one .net 4.6 the other .net core 2.2) that share an authentication cookie to a web farm environment, the "receiving" app does not authenticate. We have a very large web forms application that we are trying to eventually migrate to .net core, so for now we are handling the authentication in the web forms app and trying to share that authentication with the .net core app. We have upgraded the authentication in the web forms app to OWIN/Katana cookie based authentication. The apps are deployed on the same servers under the same site (server.com/app1 server.com/app2). Everything works fine locally, you sign in on one and move to the other and you are still logged in. When we deploy to our servers, which are load balanced, the .net core app receives the cookie, but isAuthenticated is false.
I have been able to manually decrypt the cookie in the .net core app and it is able to print out the claims contained within it, but the IsAuthenticated flag is still false. I've tried changing the cookie domain, cookie path, security policy, and authentication type with no success.
Web Forms app Startup.cs:
var provider = DataProtectionProvider.Create(new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["KeyRingLocation"]),
(builder) => {
builder.SetApplicationName("sharedApp");
builder.PersistKeysToFileSystem(new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["KeyRingLocation"]));
});
IDataProtector protector = provider.CreateProtector(
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
"Identity.Application",
"v2");
app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
{
CookieName = ".AspNet.SharedCookie",
LoginPath = new PathString("/Login.aspx"),
CookiePath = "/",
AuthenticationType = "Identity.Application",
CookieSecure = Microsoft.Owin.Security.Cookies.CookieSecureOption.Always,
CookieDomain = System.Configuration.ConfigurationManager.AppSettings["CookieDomain"],
TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(protector)),
CookieManager = new ChunkingCookieManager()
});
.net core app Startup.cs:
services.AddDataProtection()
.SetApplicationName("sharedApp")
.PersistKeysToFileSystem(new DirectoryInfo(Configuration.GetSection("KeyRingLocation").Value));
services.AddAuthentication("Identity.Application")
.AddCookie("Identity.Application", options =>
{
options.Cookie.Name = ".AspNet.SharedCookie";
options.Cookie.Domain = Configuration.GetSection("CookieDomain").Value;
options.Cookie.Path = "/";
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
web forms login code:
...
var auth = Context.GetOwinContext().Authentication;
var identity = new ClaimsIdentity("Identity.Application");
identity.AddClaim(new Claim(ClaimTypes.Name, profile.UserName));
...
auth.SignIn(identity);
There are no errors being thrown so it is really hard to figure out what the issue is. I would expect it to respect the authentication cookie as it does running locally, but the user identity is null and isAuthenticated is false.

Owin CookieDomain IIS7 and SSL

I am having a problem with setting up SSO between our apps, In the application that creates the cookie I have:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
// LogoutPath = new PathString("/Account/Logout"),
// ExpireTimeSpan = TimeSpan.FromDays(1),
CookieName = "mycookie",
CookieDomain = ".mydomain.com",
});
When testing this locally I get the result I expect
Cookie = Name: mycookie, Domain: .mydomain.com
However when I go to our test environment I get
Cookie = Name: mycookie, Domain: oauth.mydomain.com
Since the cookie has the root of the domain it does not work in the other applications. I have done everything I can think of but it just does not seem to want to use the domain specified in the configuration.
Update: It appears this is a problem when hosting from an IIS7 environment when using SSL. When not using SSL in IIS7 or when deployed to our UAT enviroment with IIS8 it works as expected.
When using SSL it is also not redirecting correctly. I think this problem is also related.
When I hit http://site.domain.com I am redirected to
http://auth.domain.com/account/login?returnUrl=site.domain.com
as expected, however If SSL is enabled I am redirected to
https://site.domain.com/account/login?returnurl=site.domain.com
So It looks like the problem is happening within a firewall/proxy those servers sit behind.

OWIN Cookie authentication not working on IIS 8.5

I have developed an ASP.NET webapp with OWIN authentication, which works fine on my development machine (Windows 10/IIS 10), but when the webapp is published to my Windows 2012 server with IIS 8.5, the cookie authentication does not seem te work.
When I login (with the IsPersistent setting to true) and close the browser, I am still logged on when I start my browser again, so that's OK. But when I restart IIS and startup the browser, I have to logon again.
I have created a very simple application to test this, with the following code:
Startup.cs
public void ConfigureAuthentication(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login"),
CookieName = "ThisIsTheAuthCookie"
});
}
AuthenticationController.cs
public ActionResult Login(string userName, string password)
{
//For testing purposes every user/pwd is fine
var identity = new ClaimsIdentity(new [] { new Claim(ClaimTypes.Name, userName), },
DefaultAuthenticationTypes.ApplicationCookie,
ClaimTypes.Name, ClaimTypes.Role);
HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true }, identity);
return RedirectToAction("index", "home");
}
Even Chrome shows the cookie, but it looks like OWIN is not using it on IIS 8.5:
Does anybody have an idea what the problem is?
Thx,
Danny
Can you try a couple of things and share the results :-
1. Restart the IIS , keeping the User-Agent. See if you are logged in now.
2. Enable logging in Katana and check for this warning/error in the logs.
Any result on this already?
For me it looks like you have the cookie with the session ID available but the IIS server is not aware anymore on this session. Are you sure you persist the session on the IIS server? (and not 'In Process')
You can find the option under Session State in the IIS configuration. See TechNet Article IIS
The problem is solved. I had to add the MachineKey element in the web.config!

Combine IdentityServer4 and MVC client

I downloaded the sample IdentityServer and MVC client project from Github.
My goal is to create a portal environment, in which a user can authenticate and than proceed to request protected resources.
So what I did is move the Views from the MVC client to the IdentityServer project, changed the Client.cs to support a client on the same port and added the following in the startup from the IdentityServer:
var oidcOptions = new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
PostLogoutRedirectUri = "http://localhost:5000/",
ClientId = "mvc",
ClientSecret = "secret",
ResponseType = "code id_token",
GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true
};
My question is are there any reasons, concerning security, I should not implement this and keep it seperated?
There is nothing wrong with this at all from a security perspective.
However I must warn you that you may run into a problem when dealing with cookies and tokens. Running them in separate projects implicitly separates the concerns of the MVC and IDS projects.
something that you might want to do is to fork your request pipeline by using app.Map(). (eg map IDS to "/identity" and the MVC project to "/ui")

Azure AD 401 error - Authenticating from angular client

I have a separate angular client that I want to authenticate to using Azure AD. I am using ADAL JS and all of that seems to be working fine. I get redirected to the AD login page, and then sent back to my application. I can see the token getting passed with each subsequent http request.
However, when I try to make a secured request to my Web API I receive a 401 Unauthorized error. I am loosely following the guide here for setup. I say loosely because I'm not using MVC, my client is in a separate codebase entirely.
I am positive that my user has access to this application.
My Auth Configuration stuff looks like:
app.UseWindowsAzureActiveDirectoryBearerAuthentication(new WindowsAzureActiveDirectoryBearerAuthenticationOptions()
{
TokenValidationParameters = new TokenValidationParameters()
{
ValidAudience = ConfigurationManager.AppSettings["AzureADAudience"],
},
Tenant = ConfigurationManager.AppSettings["AzureADTenant"],
AuthenticationType = "OAuth2Bearer"
});
Audience: https://login.windows.net/xyz.onmicrosoft.com/myappname
Tenant: xyz.onmicrosoft.com
The controller I'm locking down is decorated like this:
[HostAuthentication("OAuth2Bearer")]
[Authorize]
[RoutePrefix("Auth")]
Is your SPA hosted with your backend? If so, then you need to change your audience to the Client ID.
ValidAudience = ConfigurationManager.AppSettings["ida:ClientID"]

Categories