2013-12-16 59 views
9

我想在VS 2013中對ASP.NET的默認單頁面應用模板進行修改,該版本當前使用承載令牌認證。該示例使用app.UseOAuthBearerToken創建令牌服務器和中間件,以驗證同一應用程序中的請求的令牌。OWIN多應用不記名令牌認證

我想要做的就是保留這個位置,但添加第二個應用程序(在IIS中綁定到相同的域,不同的路徑 - 例如/ auth/*用於身份驗證服務器,/ app1/*用於該應用程序)。對於第二個應用程序,我希望它接受認證服務器在第一個應用程序中發出的令牌。這怎麼可能完成?我曾嘗試在Startup.Auth.cs剛準備關在UseOAuthBearerTokens代碼的下面,但我得到401點的響應與[授權]屬性的任何請求:

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); 
     } 
    } 

顯然我錯過了其中的一部分第二個應用程序有一些驗證令牌來自第一個應用程序的方法。某種公共簽名密鑰?

這只是一個概念證明。

編輯:對於POC演示,機器關鍵建議運行良好,並且很高興知道有AS實施選項支持其他關鍵場景。

我能夠產生一個DEMO鍵(不要在生產中使用),使用這個網站: http://aspnetresources.com/tools/machineKey

,並放置在每個應用程序中的IIS網站託管在web.config中<system.web>元素下的結果。我還必須刪除資源服務器啓動類中的一些特定於AS的配置選項。

回答

7

目前中間件(或者說生產的令牌)並不是真正用於跨應用程序的。對於這些情況,您應該使用真正的授權服務器(例如https://github.com/thinktecture/Thinktecture.AuthorizationServer)。

也就是說,您可以通過在兩個應用程序中同步機器密鑰(web.config中的machineKey元素)來使其工作。但我從來沒有嘗試過。

+1

+1在整個Web場中使用相同的機器密鑰,以允許在多個服務器上使用相同的訪問/承載令牌。今天我學會了「默認數據保護提供程序......在IIS上將使用ASP.NET機器密鑰數據保護」https://msdn.microsoft.com/en-us/library/microsoft.owin.security.oauth.oauthauthorizationserveroptions( v = vs.113).aspx – Dunc

+0

對於使用機器密鑰不是+1。整個下午一直在與這些東西作鬥爭,而機器鍵並不能解決我的問題。剛推出了我自己的IDataProtector,並試圖弄清楚如何在鏈條中實現這一切,並且我遇到的每一個樣本都會讓人感覺像機器鑰匙一樣神聖。瘸! –

0

嘗試創建自定義IDataProtector並按以下方式配置OAuthAuthorizationServerOptions

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

默認情況下,OWIN使用ASP.NET機關鍵數據保護,以保護OAuth訪問令牌在IIS上承載的時候。您可以使用System.Web.dll中的MachineKey類來解除令牌的保護。

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); 
    } 
} 

然後,構建一個TicketDataFormat得到AuthenticationTicket對象,你可以得到ClaimsIdentity和AuthenticationProperties。

var access_token="your token here"; 
var secureDataFormat = new TicketDataFormat(new MachineKeyProtector()); 
AuthenticationTicket ticket = secureDataFormat.Unprotect(access_token); 

要解除其他OAuth令牌的保護,您只需更改_purpose內容。有關詳細信息,請參見OAuthAuthorizationServerMiddleware類在這裏: 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); 
}