WebApi

2014-10-14 20 views
48

'da OAuth Bearer Jetonları Üretimi ve Owin'i kullanarak istemciye daha fazla bilgi döndürün Bir WebApi ve bir Cordova uygulaması oluşturdum. Cordova uygulaması ve WebApi arasında iletişim kurmak için http istekleri kullanıyorum. WebApi'de, OAuth Bearer Tokens Generation'ı uyguladık.WebApi

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

    } 

ve bu, ben sorundur aşağıdaki json

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

almak Cordova uygulamasından API başarılı giriş isteğinden sonra SimpleAuthorizationServerProvider uygulanması

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

içindedir Kullanıcı hakkında daha fazla bilgiye ihtiyacım var. Örneğin, veritabanında bir UserGuid alanı var ve giriş başarılı olduğunda ve daha sonra diğer isteklerde kullanmak için Cordova uygulamasına göndermek istiyorum. "access_token", "token_type" ve "expires_in" dışındaki bir kullanıcıya geri dönmek için başka bilgiler ekleyebilir miyim? Değilse, kullanıcıyı API'da access_token'u temel alarak nasıl edinebilirim?


DÜZENLEME:

Ben geçici bir çözüm buldu düşünüyorum. Ben GrantResourceOwnerCredentials

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

içine aşağıdaki kodu eklenmiş ve bundan sonra böyle benim Kontrolörün içinde guid erişmek: Ben de özel bir ad identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));

Birlikte guid ekleyebilir User.Identity.Name

Taşıyıcı jeton JSON ile müşteriye daha fazla veri döndürmenin bir yolu olup olmadığını bilmek istiyorum.

cevap

74

İstediğiniz kadar sayıda hak talebi ekleyebilirsiniz.
Standart talepler kümesini System.Security.Claims'dan ekleyebilir veya kendiniz oluşturabilirsiniz.
Talepler, şifrenizde şifrelenecek, böylece yalnızca kaynak sunucudan erişilecekler.

İstemcinizin belirtecin genişletilmiş özelliklerini okuyabilmesini istiyorsanız, başka bir seçeneğiniz vardır: AuthenticationProperties.

Müşterinizin erişebileceği bir şey eklemek istediğinizi varsayalım.sonucudur

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

müşteri alıp bunu:

.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" 

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

Şimdi yukarıda eklediğiniz özelliklere sahip bir bilet oluşturabilirsiniz: Bu gitmek için bir yoldur Diğer yandan, hak talepleri eklerseniz, bunları API sunucunuzda kaynak sunucunuzda okuyabileceksiniz:

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

    return Ok(); 
} 

Sizin ClaimsPrincipal içerecektir burada ekledik yeni iddia en guid:

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

Eğer taşıyıcı simgeleri ve gerçekten iyi bir öğretici here var web API, Owin hakkında daha fazla bilgi edinmek istiyorsanız ve bu article olacak Yetkilendirme Sunucusu ve Kaynak Sunucusu'un arkasındaki tüm kavramları kavramanıza yardımcı olur.

GÜNCELLEME:

Bir çalışma örneği here bulabilirsiniz. Bu, kendi kendini barındıran bir Web Api + Owin'dur.
Burada bir veritabanı yok. İstemci, bir Web Api geçiş kimlik bilgilerini çağıran bir konsol uygulamasıdır (bir html + JavaScript örneği de vardır).

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

Çözüm dan Enable 'Çoklu Başlangıç ​​Projeleri' -> Özellikler 've hemen çalıştırabilirsiniz: Taiseer önerilen olarak

, sen TokenEndpoint geçersiz kılmak gerekir.

+1

Cevabınız için teşekkür ederiz. API'yı yazdığımda, aynı makaleyi reddediyorum, hatta kodu indirdim ve çukura gittim. Bu yüzden “AuthenticationProperties” kullanmayı denedim, ancak sonuç aynıydı. İstemci tarafında hala sadece "access_token", "token_type" ve "expires_in" özelliklerini alıyorum. –

+0

Çözümümü bu projede test ettim ve işe yarıyor. Neler olduğunu görmek için kemancı gibi bir sniffer kullanıyor musunuz? – LeftyX

+0

Evet. Fiddler kullanıyorum ve aynı zamanda API’yi de ayıklamıyorum, ancak sonuç hala aynı. –

37

Önerim, gerekmediğinde belirticiye ek hak talepleri eklemek değildir, çünkü belirtecin boyutunu artıracak ve her istekte göndermeye devam edeceksiniz. LeftyX tarafından önerildiği gibi, bunları özellikler olarak ekleyin, ancak bu belirteci başarılı bir şekilde aldığınızda yanıt olarak bu özellikleri almak için TokenEndPoint yöntemini geçersiz kıldığınızdan emin olun, bu nokta olmadan özellikler yanıtta geri dönmez.

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

Örnek için my repo kontrol edebilirsiniz. Umarım yardımcı olur.

+0

@TaiseerJoudeh, özelliklerden biri olarak bir dizi dizeyi koyabilir miyim? Asp.Net Çekirdeği için [ASOS] (https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server) ile bugün itibariyle – pomber

+0

izinlerinin bir listesini göndermem gerekiyor, işler değişmiş gibi görünüyor. biraz. context.Properties.Dictionary; 'context.Ticket.Properties.Items', ancak context.AdditionalResponseParameters 'eşdeğerini bulamıyorum. Herhangi birisi bunu biliyor mu? – superjos

+0

Nevermind, [bu] ile bağlantı kurdu (http://stackoverflow.com/questions/34074787/overriding-tokenendpoint-in-aspnet-security-openidconnect-server/34093112#34093112) ASOS yazarı – superjos