2013-12-16 15 views
9

Ich möchte eine Änderung an der standardmäßigen Single-Page-Anwendungsvorlage für ASP.NET in VS 2013, die derzeit Bearer-Token-Authentifizierung verwendet. Das Beispiel verwendet app.UseOAuthBearerTokens, um sowohl den Token-Server als auch die Middleware zu erstellen, um Token für Anfragen in derselben App zu validieren.OWIN Multi-App-Bearer-Token-Authentifizierung

Ich möchte das an Ort und Stelle, aber fügen Sie eine zweite Anwendung (gebunden in IIS zu derselben Domäne, anderen Pfad - zB/auth/* für den Authentifizierungsserver und/app1/* für die App). Für die zweite App möchte ich Token akzeptieren, die vom Authentifizierungsserver in der ersten App ausgegeben wurden. Wie könnte dies erreicht werden? die folgenden in Startup.Auth.cs nur abgehend des Codes in UseOAuthBearerTokens Ich habe versucht, aber ich erhalte 401 Antworten auf alle Anfragen mit dem [autorisieren] Attribut:

public partial class Startup 
{ 
    static Startup() 
    { 
     PublicClientId = "self"; 

     UserManagerFactory =() => new UserManager<IdentityUser>(new UserStore<IdentityUser>()); 

     OAuthOptions = new OAuthAuthorizationServerOptions 
     { 
      //TokenEndpointPath = new PathString("/Token"), 
      Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory), 
      //AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), 
      //AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 
      AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, 
      AuthenticationType = "ExternalBearer", 
      AllowInsecureHttp = true, 
     }; 
    } 

    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } 

    public static Func<UserManager<IdentityUser>> UserManagerFactory { get; set; } 

    public static string PublicClientId { get; private set; } 

    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 
    public void ConfigureAuth(IAppBuilder app) 
    { 
     //// Enable the application to use a cookie to store information for the signed in user 
     //// and to use a cookie to temporarily store information about a user logging in with a third party login provider 
     //app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
     //app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

     OAuthBearerAuthenticationOptions bearerOptions = new OAuthBearerAuthenticationOptions(); 
     bearerOptions.AccessTokenFormat = OAuthOptions.AccessTokenFormat; 
     bearerOptions.AccessTokenProvider = OAuthOptions.AccessTokenProvider; 
     bearerOptions.AuthenticationMode = OAuthOptions.AuthenticationMode; 
     bearerOptions.AuthenticationType = OAuthOptions.AuthenticationType; 
     bearerOptions.Description = OAuthOptions.Description; 
     bearerOptions.Provider = new CustomBearerAuthenticationProvider(); 
     bearerOptions.SystemClock = OAuthOptions.SystemClock; 
     OAuthBearerAuthenticationExtensions.UseOAuthBearerAuthentication(app, bearerOptions); 
    } 
} 

public class CustomBearerAuthenticationProvider : OAuthBearerAuthenticationProvider 
    { 
     public override Task ValidateIdentity(OAuthValidateIdentityContext context) 
     { 
      var claims = context.Ticket.Identity.Claims; 
      if (claims.Count() == 0 || claims.Any(claim => claim.Issuer != "LOCAL AUTHORITY")) 
       context.Rejected(); 
      return Task.FromResult<object>(null); 
     } 
    } 

Offensichtlich fehlt mir der Teil, in dem Die zweite App hat eine Möglichkeit zu validieren, dass die Token von der ersten App kamen. Ein öffentlicher Signierschlüssel?

Dies ist nur für einen Proof of Concept.

Bearbeiten: Der Maschinenschlüsselvorschlag funktionierte gut genug für die POC-Demo, und es ist gut zu wissen, dass es AS-Implementierungsoptionen gibt, die andere Schlüsselszenarien unterstützen.

konnte ich eine DEMO-Taste der Nutzung dieser Website (nicht für die Produktion verwendet werden) erzeugen: http://aspnetresources.com/tools/machineKey

und stellte das Ergebnis unter dem <system.web> Elemente in der web.config jedem in der IIS-Website gehostet App . Ich musste auch einige AS-spezifische Konfigurationsoptionen in der Startup-Klasse des Ressourcenservers entfernen.

Antwort

7

Momentan ist die Middleware (oder vielmehr das erstellte Token) nicht wirklich dafür ausgelegt, anwendungsübergreifend zu arbeiten. Für dieses Szenario sollten Sie lieber einen echten Autorisierungsserver verwenden (z. B. https://github.com/thinktecture/Thinktecture.AuthorizationServer).

Das heißt, Sie könnten es funktionieren, indem Sie den Computerschlüssel (machineKey -Element in web.config) in beiden Anwendungen synchronisieren. Aber ich habe es nie versucht.

+1

+1 für die Verwendung desselben Maschinenschlüssels über eine Webfarm, um denselben Zugriffs-/Bearer-Token auf mehreren Servern zu ermöglichen. Heute habe ich gelernt, "der Standard-Datenschutz-Provider ... auf IIS wird ASP.NET-Rechnerschlüssel Datenschutz verwenden" https://msdn.microsoft.com/en-us/library/microsoft.owin.security.oauth.oauthauthorizationserveroptions (v = vs.113) .aspx – Dunc

+0

nicht +1 für die Verwendung von Maschinenschlüssel. Ich habe diesen ganzen Nachmittag mit diesem Zeug gekämpft, und der Maschinenschlüssel wird mein Problem nicht lösen. Ich habe gerade meinen eigenen IDataProtector gerollt und versucht herauszufinden, wie ich alles in die Kette bekommen kann und jedes Sample, auf das ich stoße, kotzt Maschinenschlüssel heraus, als wäre es der Heilige Gral. Lame! –

0

Versuchen Sie, eine benutzerdefinierte IDataProtector zu erstellen, und konfigurieren Sie Ihre OAuthAuthorizationServerOptions auf die folgende Weise.

AuthorizationCodeFormat = new TicketDataFormat(new CustomDataProtector()), 
    RefreshTokenFormat = new TicketDataFormat(new CustomDataProtector()), 
    AccessTokenFormat = new TicketDataFormat(new CustomDataProtector()), 
3

OWIN verwendet standardmäßig ASP.NET-Computerschlüsseldatenschutz, um das OAuth-Zugriffstoken zu schützen, wenn es auf IIS gehostet wird. Sie können die MachineKey-Klasse in System.Web.dll verwenden, um die Token aufzuheben.

public class MachineKeyProtector : IDataProtector 
{ 
    private readonly string[] _purpose = 
    { 
     typeof(OAuthAuthorizationServerMiddleware).Namespace, 
     "Access_Token", 
     "v1" 
    }; 

    public byte[] Protect(byte[] userData) 
    { 
     throw new NotImplementedException(); 
    } 

    public byte[] Unprotect(byte[] protectedData) 
    { 
     return System.Web.Security.MachineKey.Unprotect(protectedData, _purpose); 
    } 
} 

Dann bauen eine TicketDataFormat das AuthenticationTicket-Objekt zu erhalten, wo Sie die ClaimsIdentity und AuthenticationProperties bekommen.

Um andere OAuth-Tokens zu schützen, müssen Sie nur den _purpose-Inhalt ändern. Ausführliche Informationen finden Sie OAuthAuthorizationServerMiddleware Klasse hier: http://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.OAuth/OAuthAuthorizationServerMiddleware.cs

if (Options.AuthorizationCodeFormat == null) 
{ 
    IDataProtector dataProtecter = app.CreateDataProtector(
     typeof(OAuthAuthorizationServerMiddleware).FullName, 
     "Authentication_Code", "v1"); 

    Options.AuthorizationCodeFormat = new TicketDataFormat(dataProtecter); 
} 
if (Options.AccessTokenFormat == null) 
{ 
    IDataProtector dataProtecter = app.CreateDataProtector(
     typeof(OAuthAuthorizationServerMiddleware).Namespace, 
     "Access_Token", "v1"); 
    Options.AccessTokenFormat = new TicketDataFormat(dataProtecter); 
} 
if (Options.RefreshTokenFormat == null) 
{ 
    IDataProtector dataProtecter = app.CreateDataProtector(
     typeof(OAuthAuthorizationServerMiddleware).Namespace, 
     "Refresh_Token", "v1"); 
    Options.RefreshTokenFormat = new TicketDataFormat(dataProtecter); 
}