簡體   English   中英

OWIN多應用承載令牌認證

[英]OWIN multi-app bearer token authentication

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

我想做的是保留原樣,但添加第二個應用程序(在IIS中綁定到同一個域,不同的路徑 - 例如/ auth / *用於身份驗證服務器,/ app1 / *用於應用程序)。 對於第二個應用程序,我希望它接受第一個應用程序中的身份驗證服務器發出的令牌。 怎么可以實現呢? 我在Startup.Auth.cs中嘗試了以下內容,只是關閉了UseOAuthBearerTokens中的代碼,但我得到了對[Authorize]屬性的任何請求的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>元素下。 我還必須刪除資源服務器的Startup類中的一些特定於AS的配置選項。

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

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

默認情況下,OWIN使用ASP.NET機器密鑰數據保護來保護在IIS上托管時的OAuth訪問令牌。 您可以在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);
}

雖然目前列出的答案非常好,但我已經使用了以下幾次並取得了巨大的成功。 在web.config中設置機器密鑰效果很好。 確保使用microsoft站點的powershell生成自己的! http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM