I have an Owin application that I run in Mono and am trying to authenticate on it. I used the information in this page as a start. I quickly realized that Owin Authentication uses some specific Windows libraries. This question had a workaround for this, although it seemed to me that was enough. This is not true.
The following code throws an exception described in another question (in a different place than the question describes (see the comment in the code)). If I try to comment on material to detect errors related to the Owin pipeline, it gets called (due to dependencies). If I comment enough to remove this first exception, it will appear again.
Has anyone successfully configured authentication in Owin (using AspNet Identity) in Mono?
Enter
public void Configure(IAppBuilder app)
{
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
TicketDataFormat = new SecureDataFormat<AuthenticationTicket>(
DataSerializers.Ticket,
new AesDataProtectorProvider("myAuthKey"),
TextEncodings.Base64)
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.Use(typeof(AuthMiddleware), app, new AuthOptions());
}
AuthMiddleware
public class AuthMiddleware : AuthenticationMiddleware<AuthOptions>
{
public AuthMiddleware(OwinMiddleware next, IAppBuilder app, AuthOptions options)
: base(next, options)
{
if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType))
{
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
}
if (options.StateDataFormat == null)
{
var dataProtector = app.CreateDataProtector(typeof(AuthMiddleware).FullName,
options.AuthenticationType);
options.StateDataFormat = new PropertiesDataFormat(dataProtector);
}
}
protected override AuthenticationHandler<AuthOptions> CreateHandler()
{
return new AuthHandler();
}
}
Authoptions
public class AuthOptions : AuthenticationOptions
{
public AuthOptions()
: base("MyApp")
{
Description.Caption = "MyApp";
CallbackPath = new PathString("/login"); AuthenticationMode = AuthenticationMode.Passive;
}
public PathString CallbackPath { get; set; }
public string SignInAsAuthenticationType { get; set; }
public ISecureDataFormat<AuthenticationProperties> StateDataFormat { get; set; }
}
Authhandler
public class AuthHandler : AuthenticationHandler<AuthOptions>
{
protected override Task<AuthenticationTicket> AuthenticateCoreAsync()
{
var identity = new ClaimsIdentity(Options.SignInAsAuthenticationType);
var properties = Options.StateDataFormat.Unprotect(Request.Query["state"]);
return Task.FromResult(new AuthenticationTicket(identity, properties));
}
protected override Task ApplyResponseChallengeAsync()
{
if (Response.StatusCode == 401)
{
var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);
if (challenge != null)
{
var state = challenge.Properties;
if (string.IsNullOrEmpty(state.RedirectUri))
{
state.RedirectUri = Request.Uri.ToString();
}
var stateString = Options.StateDataFormat.Protect(state);
Response.Redirect(WebUtilities.AddQueryString(Options.CallbackPath.Value, "state", stateString));
}
}
return Task.FromResult<object>(null);
}
public override async Task<bool> InvokeAsync()
{
Request.Environment.Add("Context", Context);
if (Context.Authentication.User == null &&
!Request.Path.ToString().StartsWith("/login"))
{
Response.Redirect(Options.CallbackPath.Value);
return true;
}
return false;
}
}