2013-12-16 20 views
9

Tôi muốn thực hiện sửa đổi đối với mẫu ứng dụng trang đơn mặc định cho ASP.NET trong VS 2013, hiện đang sử dụng xác thực mã thông báo mang. Mẫu sử dụng app.UseOAuthBearerTokens để tạo cả máy chủ mã thông báo và phần mềm trung gian để xác thực mã thông báo cho các yêu cầu trong cùng một ứng dụng.Xác thực mã thông báo mang nhiều ứng dụng OWIN

Điều tôi muốn làm là để nguyên tại chỗ, nhưng thêm ứng dụng thứ hai (được liên kết trong IIS vào cùng một miền, đường dẫn khác - ví dụ/auth/* cho máy chủ xác thực và/app1/* cho ứng dụng). Đối với ứng dụng thứ hai, tôi muốn nó chấp nhận mã thông báo do máy chủ xác thực cấp trong ứng dụng đầu tiên. Làm thế nào điều này có thể được thực hiện? Tôi đã thử những điều sau đây trong Startup.Auth.cs chỉ đi tắt của mã trong UseOAuthBearerTokens, nhưng tôi nhận được 401 phản ứng với bất kỳ yêu cầu với các [Duyệt] thuộc tính:

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

Rõ ràng tôi là thiếu một phần, nơi ứng dụng thứ hai có một số cách xác thực rằng mã thông báo đến từ ứng dụng đầu tiên. Một chìa khóa ký công khai của một số loại?

Đây chỉ là bằng chứng về khái niệm.

Chỉnh sửa: Đề xuất khóa máy hoạt động tốt đủ cho bản trình diễn POC và bạn nên biết có các tùy chọn triển khai AS hỗ trợ các tình huống chính khác.

tôi đã có thể tạo ra một chìa khóa DEMO (không sử dụng phục vụ sản xuất) sử dụng trang web này: http://aspnetresources.com/tools/machineKey

Và đặt kết quả dưới các yếu tố <system.web> trong web.config của từng ứng dụng lưu trữ trong trang web IIS . Tôi cũng đã phải loại bỏ một số tùy chọn cấu hình AS cụ thể trong lớp Khởi động của máy chủ tài nguyên.

Trả lời

7

Hiện tại phần mềm trung gian (hoặc đúng hơn là mã thông báo được sản xuất) không thực sự được thiết kế để hoạt động chéo. Đối với những trường hợp này, bạn nên sử dụng máy chủ ủy quyền thực (ví dụ: https://github.com/thinktecture/Thinktecture.AuthorizationServer).

Điều đó nói rằng bạn có thể làm cho nó hoạt động bằng cách đồng bộ hóa phím máy (phần tử machineKey trong web.config) trong cả hai ứng dụng. Nhưng tôi chưa bao giờ thử nó.

+1

+1 để sử dụng cùng một khóa máy trên một trang trại, để cho phép cùng một mã thông báo truy cập/bộ râu trên nhiều máy chủ. Hôm nay tôi đã học "nhà cung cấp bảo vệ dữ liệu mặc định ... trên IIS sẽ sử dụng bảo vệ dữ liệu khóa máy ASP.NET" https://msdn.microsoft.com/en-us/library/microsoft.owin.security.oauth.oauthauthorizationserveroptions (v = vs.113) .aspx – Dunc

+0

không +1 để sử dụng phím máy. Được chiến đấu công cụ này tất cả các buổi chiều và chìa khóa máy sẽ không sửa chữa vấn đề của tôi. Chỉ cần cuộn IDataProtector của riêng tôi và cố gắng tìm hiểu làm thế nào để có được tất cả trong chuỗi và mỗi mẫu tôi đi qua những người nôn ra chìa khóa máy như đó là chén thánh. Què! –

0

Thử tạo IDataProtector tùy chỉnh và định cấu hình OAuthAuthorizationServerOptions của bạn theo cách sau.

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

Theo mặc định, OWIN sử dụng bảo vệ dữ liệu khóa máy ASP.NET để bảo vệ mã thông báo truy cập OAuth khi được lưu trữ trên IIS. Bạn có thể sử dụng lớp MachineKey trong System.Web.dll để không bảo vệ các mã thông báo.

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

Sau đó, hãy tạo TicketDataFormat để nhận đối tượng AuthenticTicket nơi bạn có thể nhận Xác nhận quyền sở hữu và xác thực.

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

Để không bảo vệ mã thông báo OAuth khác, bạn chỉ cần thay đổi nội dung _purpose. Để biết thông tin chi tiết, xem OAuthAuthorizationServerMiddleware lớp ở đây: 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); 
} 
Các vấn đề liên quan