2017-02-24 1 views
0

Ich habe einen Beispielidentitätsdienst erstellt. Es liest einen geheimen Schlüssel aus der Konfigurationsdatei.Benutzerspezifisches Geheimnis für JWT in OWIN basierend auf Anforderungsparameter

ConfigurationManager.AppSettings["as:AudienceSecret"] 

Ich brauche es zu ändern, das Geheimnis aus einer Datenbank zu lesen, auf der Grundlage der Körperparameter der eingehenden Anfragen (form["CurrentUser"]). Wie können wir das tun?

Startup.cs Konfiguration

private void ConfigureOAuthTokenGeneration(IAppBuilder app) 
    { 

     app.CreatePerOwinContext(ApplicationDbContext.Create); 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create); 

     string issuer = ConfigurationManager.AppSettings["Issuer"]; 
     OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 
     { 

      AllowInsecureHttp = true, 
      TokenEndpointPath = new PathString("/oauth/token"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
      Provider = new CustomOAuthProvider(), 
      AccessTokenFormat = new CustomJwtFormat(issuer) 
     }; 

     // OAuth 2.0 Bearer Access Token Generation 
     app.UseOAuthAuthorizationServer(OAuthServerOptions); 
    } 
private void ConfigureOAuthTokenConsumption(IAppBuilder app) 
     { 
      string issuer = ConfigurationManager.AppSettings["Issuer"]; 

      string audienceId = ConfigurationManager.AppSettings["as:AudienceId"]; 
      byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]); 

     app.UseJwtBearerAuthentication(
      new JwtBearerAuthenticationOptions 
      { 
       AuthenticationMode = AuthenticationMode.Active, 
       AllowedAudiences = new[] { audienceId }, 
       IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
       { 
        new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret) 
       } 
      }); 
    } 

GrantResourceOwnerCredentials in CustomOAuthProvider

public override async Task 
GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
{ 

    var allowedOrigin = ConfigurationManager.AppSettings["AllowedOrigin"]; 
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin }); 
    var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); 


    ApplicationUser user = null; 
    try 
    { 
     user = await userManager.FindAsync(context.UserName, context.Password); 
    } 
    catch (Exception ex) 
    { 
     string result = ex.Message; 
     string innerText = ex.InnerException.ToString(); 
    } 

    if (user == null) 
    { 
     context.SetError("invalid_grant", "The user name or password is incorrect."); 
     return; 
    } 

    var form = await context.Request.ReadFormAsync(); 
    var loggedinUserName = form["CurrentUser"]; 
    string practice = null; 
    if (!String.IsNullOrWhiteSpace(loggedinUserName)) 
    { 
     ApplicationUser loggedinUserObj = userManager.FindByName(loggedinUserName); 
     string loggedinUserID = loggedinUserObj == null ? "" : loggedinUserObj.Id; 

     if (loggedinUserID != null) 
     { 
      ProvidersBL providersBL = new ProvidersBL(); 
      practice = providersBL.GetPracticeForUser(loggedinUserID); 
     } 
    } 

    practice = practice ?? "Undefined"; 
    loggedinUserName = loggedinUserName ?? "Undefined"; 


    var claims = new List<Claim>(); 
    claims.Add(new Claim(ClaimTypes.Name, loggedinUserName)); 
    claims.Add(new Claim("Practice", practice)); 
    var oAuthIdentity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie); 
    var ticket = new AuthenticationTicket(oAuthIdentity, null); 
    context.Validated(ticket); 

} 
+0

Warum brauchen Sie das? Das Geheimnis ist es, die Anwendung (Client) nicht den Benutzer –

+0

@ CallbackKid [JWT Pro-User Signing Key] (https://auth0.com/forum/t/jwt-per-user-signing-key/485) zu bestätigen sagt "Der Ansatz, den Sie erwähnen, ist definitiv ein gültiger." – Lijo

+0

Eine weitere Referenz: [Single-Use-Token mit JWT] (https://www.jbspeakr.cc/howto-single-use-jwt/) – Lijo

Antwort

0

Folgende Arbeiten. Nicht sicher, ob dies die beste Lösung ist.

Hinweis: Ich entschied mich später nicht für verschiedene Benutzer verschiedenen Schlüssel verwenden. Der Schlüssel wird für alle Benutzer gleich sein. Es wird jedoch ein benutzerspezifischer Schlüssel für jeden Benutzer innerhalb des Tokens als Anspruch eingefügt. Dieser Schlüssel wird in der Datenbank aktualisiert, sobald der Benutzer ihn einmal verwendet hat. Beim nächsten Mal wird der Benutzerschlüssel im Token für denselben Benutzer unterschiedlich sein.

public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket> 
    { 

     private readonly string _issuer = string.Empty; 
     private ProvidersBL providerBL; 
     public CustomJwtFormat(string issuer) 
     { 
      _issuer = issuer; 
      providerBL = new ProvidersBL(); 
     } 

     public string Protect(AuthenticationTicket data) 
     { 
      if (data == null) 
      { 
       throw new ArgumentNullException("data"); 
      } 

      string userName = String.Empty; 
      var userNameClaim = data.Identity.Claims.FirstOrDefault(claim => claim.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"); 
      if (userNameClaim != null) 
      { 
       userName = userNameClaim.Value; 
      } 


      string audienceId = ConfigurationManager.AppSettings["as:AudienceId"]; 
      string symmetricKeyAsBase64 = string.Empty; 
      symmetricKeyAsBase64 = providerBL.GetKeyForUser(userName); 
      if (String.IsNullOrWhiteSpace(symmetricKeyAsBase64)) 
      { 
       symmetricKeyAsBase64 = ConfigurationManager.AppSettings["as:AudienceSecret"]; 
      } 


      var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64); 
      var signingKey = new HmacSigningCredentials(keyByteArray); 


      var issued = data.Properties.IssuedUtc; 
      var expires = data.Properties.ExpiresUtc; 
      var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey); 
      var handler = new JwtSecurityTokenHandler(); 
      var jwt = handler.WriteToken(token); 
      return jwt; 
     } 

     public AuthenticationTicket Unprotect(string protectedText) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
Verwandte Themen