web-dev-qa-db-ja.com

OAuth Bearer Tokens GenerationとWebApiのOwinを使用して、クライアントに詳細情報を返します

WebApiとCordovaアプリケーションを作成しました。 HTTP要求を使用してCordovaアプリケーションとWebAPIの間で通信しています。 WebAPIでは、OAuth Bearer Token Generationを実装しました。

public void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider(new UserService(new Repository<User>(new RabbitApiObjectContext()), new EncryptionService()))
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }

これはSimpleAuthorizationServerProvider実装内にあります

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
       context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        // A little hack. context.UserName contains the email
        var user = await _userService.GetUserByEmailAndPassword(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "Wrong email or password.");
            return;
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim("sub", context.UserName));
        identity.AddClaim(new Claim("role", "user"));

        context.Validated(identity);
    }

cordovaアプリからAPIへのログインリクエストが成功した後、次のJSONを受け取ります

{"access_token":"some token","token_type":"bearer","expires_in":86399}

問題は、ユーザーに関する詳細情報が必要なことです。たとえば、データベースにUserGuidフィールドがあり、ログインが成功したときにCordovaアプリに送信し、後で他のリクエストで使用したい。 "access_token", "token_type"および"expires_in"以外の、クライアントに返す他の情報を含めることはできますか?そうでない場合、access_tokenに基づいてAPIでユーザーを取得するにはどうすればよいですか?


編集:

私は回避策を見つけたと思います。 GrantResourceOwnerCredentials内に次のコードを追加しました

identity.AddClaim(new Claim(ClaimTypes.Name, user.UserGuid.ToString()));

その後、次のようにコントローラー内のGUIDにアクセスします:User.Identity.Name

カスタム名identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));でguidを追加することもできます

ベアラートークンJSONを使用して、より多くのデータをクライアントに返す方法があるかどうかを知りたいと思っています。

61
Ivan Stoyanov

必要な数のクレームを追加できます。
System.Security.Claimsから標準のクレームセットを追加するか、独自のクレームを作成できます。
クレームはトークンで暗号化されるため、リソースサーバーからのみアクセスできます。

クライアントがトークンの拡張プロパティを読み取れるようにする場合は、別のオプションAuthenticationPropertiesを使用します。

クライアントがアクセスできるように何かを追加したいとしましょう。それは行く方法です:

var props = new AuthenticationProperties(new Dictionary<string, string>
{
    { 
        "surname", "Smith"
    },
    { 
        "age", "20"
    },
    { 
    "gender", "Male"
    }
});

これで、上記で追加したプロパティを使用してチケットを作成できます。

var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);

クライアントが取得する結果は次のとおりです。

.expires: "Tue, 14 Oct 2014 20:42:52 GMT"
.issued: "Tue, 14 Oct 2014 20:12:52 GMT"
access_token: "blahblahblah"
expires_in: 1799
age: "20"
gender: "Male"
surname: "Smith"
token_type: "bearer"

一方、クレームを追加すると、APIコントローラーのリソースサーバーでそれらを読み取ることができます。

public IHttpActionResult Get()
{
    ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;

    return Ok();
}

ClaimsPrincipalには、ここに追加した新しい申し立てのguidが含まれます。

identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));

Owin、ベアラートークン、Web APIについて詳しく知りたい場合は、本当に良いチュートリアルがあります here と、この article は、背後にあるすべての概念を理解するのに役立ちます認可サーバーおよびリソースサーバー

UPDATE

実際の例を見つけることができます here 。これは、Web Api+Owin自己ホスト型です。
ここに関係するデータベースはありません。クライアントは、資格情報を渡すWeb Apiを呼び出すコンソールアプリケーションです(html + JavaScriptサンプルもあります)。

Taiseerが提案したように、TokenEndpointをオーバーライドする必要があります:

public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
    foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
    {
        context.AdditionalResponseParameters.Add(property.Key, property.Value);
    }

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

ソリューション->プロパティから「複数のスタートアッププロジェクト」を有効にすると、すぐに実行できます。

90
LeftyX

トークンのサイズが大きくなり、リクエストごとに送信し続けるため、不要な場合はトークンに追加のクレームを追加しないことをお勧めします。 LeftyXがアドバイスとしてそれらをプロパティとして追加しますが、トークンを正常に取得した場合、TokenEndPointメソッドをオーバーライドしてこれらのプロパティを応答として取得するようにしてください。

 public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
        {
            context.AdditionalResponseParameters.Add(property.Key, property.Value);
        }

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

完全な例については、ここで my repo を確認できます。それが役立つことを願っています。

43
Taiseer Joudeh