web-dev-qa-db-ja.com

OWINのOAuth Bearer TokenからIPrincipalを取得

OWINを使用してWebAPI 2プロジェクトにOAuthを追加しました。トークンを受け取り、HTTPヘッダーでトークンを使用してリソースにアクセスできます。

ここで、OWINテンプレートが作成される標準のHTTPリクエストではない認証用の他のチャネルでもこれらのトークンを使用したいと思います。たとえば、認証のためにクライアントがOAuth Bearer Tokenを送信する必要があるWebSocketsを使用しています。

サーバー側では、WebSocketを介してトークンを受け取ります。 しかし、このトークンをOWINパイプラインに入れてIPrincipalとClientIdentifierを抽出するにはどうすればよいですか? WebApi 2テンプレートでは、これはすべて抽象化されているので、する必要はありません動作させる。

したがって、基本的に、トークンを文字列として使用しており、OWINを使用して、そのトークンにエンコードされたユーザー情報にアクセスしたい

助けてくれてありがとう。

30

このブログ投稿で解決策の一部を見つけました: http://leastprivilege.com/2013/10/31/retrieving-bearer-tokens-from-alternative-locations-in-katanaowin/

そこで、次のように独自のプロバイダーを作成しました。

public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider
{
    public override Task RequestToken(OAuthRequestTokenContext context)
    {
        var value = context.Request.Query.Get("access_token");

        if (!string.IsNullOrEmpty(value))
        {
            context.Token = value;
        }

        return Task.FromResult<object>(null);
    }
}

次に、Startup.Auth.csで次のようにアプリに追加する必要がありました。

OAuthBearerOptions = new OAuthBearerAuthenticationOptions()
{
   Provider = new QueryStringOAuthBearerProvider(),
   AccessTokenProvider = new AuthenticationTokenProvider()
   {
       OnCreate = create,
       OnReceive = receive
   },
};

app.UseOAuthBearerAuthentication(OAuthBearerOptions);

カスタムAuthenticationTokenProviderを使用すると、パイプラインの早い段階でトークンから他のすべての値を取得できます。

public static Action<AuthenticationTokenCreateContext> create = new Action<AuthenticationTokenCreateContext>(c =>
{
    c.SetToken(c.SerializeTicket());
});

public static Action<AuthenticationTokenReceiveContext> receive = new Action<AuthenticationTokenReceiveContext>(c =>
{
    c.DeserializeTicket(c.Token);
    c.OwinContext.Environment["Properties"] = c.Ticket.Properties;
});

そして今、たとえば私のWebSocket Handerで、ClientIdと次のような他のものを取得できます。

IOwinContext owinContext = context.GetOwinContext();
if (owinContext.Environment.ContainsKey("Properties"))
{
    AuthenticationProperties properties = owinContext.Environment["Properties"] as AuthenticationProperties;
    string clientId = properties.Dictionary["clientId"];
...
 }
28

既定では、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);
}
9
Johnny Qian

johnny-qian answerに加えて、この方法を使用するとDataProtectorを作成する方が適切です。 johnny-qian回答、IISに依存し、自己ホスト型シナリオでは失敗します。

using Microsoft.Owin.Security.DataProtection;
var dataProtector = app.CreateDataProtector(new string[]   {
     typeof(OAuthAuthorizationServerMiddleware).Namespace,
     "Access_Token",
     "v1"
});
1
Mahmoud Moravej

トークンはどのようなものですか、暗号化文字列ですか、フォーマットされた文字列ですか?フォーマットは何ですか?

私のコード:

public static Action<AuthenticationTokenReceiveContext> receive = new Action<AuthenticationTokenReceiveContext>(c =>
{
        if (!string.IsNullOrEmpty(c.Token))
        {

            c.DeserializeTicket(c.Token);
            //c.OwinContext.Environment["Properties"] = c.Ticket.Properties;
        }
});

C.Ticketは常にnullです。

0
Nguyen Tu Pham