Δύναμη το middleware έλεγχο ταυτότητας να δέχεται μόνο κρυπτογραφημένα μάρκες

ψήφοι
1

Σύμφωνα με αυτό το θέμα , είμαι χρησιμοποιώντας το παρακάτω απόσπασμα, να υπογράψουν και να κρυπτογραφήσετε το JWToken.

var claims = new Claim[] { new SomeClaimes() };
var scKey = Encoding.UTF8.GetBytes(SOME KEY);
var ecKeyTemp = Encoding.UTF8.GetBytes(SOME OTHER KEY);

byte[] ecKey = new byte[256 / 8];
Array.Copy(ecKeyTemp, ecKey, 256 / 8);

var tokenDescriptor = new SecurityTokenDescriptor {
    Subject = new ClaimsIdentity(claims),
    SigningCredentials = new SigningCredentials(
        new SymmetricSecurityKey(
            scKey),
            SecurityAlgorithms.HmacSha512),
    EncryptingCredentials = new EncryptingCredentials(
        new SymmetricSecurityKey(
            ecKey),
            SecurityAlgorithms.Aes256KW,
            SecurityAlgorithms.Aes256CbcHmacSha512), 
    Issuer = My Jwt Issuer,
    Audience = My Jwt Audience,
    IssuedAt = DateTime.UtcNow,
    Expires = DateTime.Now.AddDays(7),
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
var jwt = tokenHandler.WriteToken(token);

Και εδώ είναι η καταγραφή της υπηρεσίας μου:

services
.AddAuthentication(o => {
    o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(cfg => {
    cfg.RequireHttpsMetadata = false;
    cfg.SaveToken = true;
    cfg.TokenValidationParameters = new TokenValidationParameters {
        ValidIssuer = My Jwt Issuer,
        ValidAudience = My Jwt Audience,
        IssuerSigningKey = new SymmetricSecurityKey(SameKeyAsGenerating)),
        TokenDecryptionKey = new SymmetricSecurityKey(SameKeyAsGenerating),
        ClockSkew = TimeSpan.Zero, 
        RequireSignedTokens = true,
        RequireExpirationTime = true,
        SaveSigninToken = true,
        ValidateActor = true,
        ValidateAudience = true,
        ValidateIssuer = true,
        ValidateIssuerSigningKey = true,
        ValidateLifetime = true,
        ValidateTokenReplay = true,
    };
});

Το πρόβλημα είναι ότι το στρώμα πιστοποίηση επικυρώνει τόσο κρυπτογραφημένα και μη κρυπτογραφημένα συμβολική ως εξουσιοδοτημένο. Θέλω να πω, όταν δημιουργώ ένα συμβολικό χωρίς EncryptingCredentials(μόλις υπογραφεί συμβολική, και όχι κρυπτογραφημένα), το κουπόνι εξακολουθεί να ισχύει και η αίτηση έχει εγκριθεί. Το ερώτημα είναι πώς να αναγκάσει επίπεδο ελέγχου ταυτότητας για να δέχονται μόνο υπέγραψε κρυπτογραφημένο μάρκες και απορρίπτουν απλά-υπέγραψε-δεν-κρυπτογραφημένα σύμβολα;

UPDATE: Η Λύση:

Χάρη στην απάντηση σελοτέιπ του , θα εφαρμοστεί αυτό JwtEncryptedSecurityTokenHandler:

public class JwtEncryptedSecurityTokenHandler : JwtSecurityTokenHandler {

    [DebuggerStepThrough]
    public override ClaimsPrincipal ValidateToken(string token, TokenValidationParameters validationParameters, out SecurityToken validatedToken) {
        if (string.IsNullOrWhiteSpace(token))
            throw new ArgumentNullException(nameof (token));

        if (validationParameters == null)
            throw new ArgumentNullException(nameof (validationParameters));

        if (token.Length > MaximumTokenSizeInBytes)
            throw new ArgumentException(
                $IDX10209: token has length: '{token.Length}' which is larger than the MaximumTokenSizeInBytes: '{MaximumTokenSizeInBytes}'.);

        var strArray = token.Split(new[] { '.' }, 6);
        if (strArray.Length == 5)
            return base.ValidateToken(token, validationParameters, out validatedToken);

        throw new SecurityTokenDecryptionFailedException();
    }
}

Και χρησιμοποίησε το νέο χειριστή σε Startup.ConfigureServices():

.AddJwtBearer(cfg => {
    cfg.RequireHttpsMetadata = false;
    // other configurations...
    cfg.SecurityTokenValidators.Clear();
    cfg.SecurityTokenValidators.Add(new JwtEncryptedSecurityTokenHandler());
});

Για περισσότερες εξηγήσεις, δείτε την αποδεκτή απάντηση.

Δημοσιεύθηκε 27/11/2018 στις 17:37
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
1

Είμαι βέβαιος ότι υπάρχουν μερικοί τρόποι για να γίνει αυτό, αλλά τι θα έλεγες για:

  • Εφαρμογή ISecurityTokenValidator, πιθανότατα κληρονομεί από SecurityTokenHandler? οι απαιτούμενες παρακάμψεις είναι αρκετά απλή και θα μπορούσε σε μεγάλο βαθμό να αντιγραφεί από JwtSecurityTokenHandler. Παράκαμψη ValidateToken()και να ρίξει αν η JWT δεν είναι κρυπτογραφημένη **.

  • Προσθέστε το νέο χειριστή / επικύρωσης της AddJwtBearer()δράσης ρυθμίσετε επιλογές:cfg.SecurityTokenValidators.Add(new RequireEncryptedTokenHandler());


** Αν κοιτάξετε την πηγήJwtSecurityTokenHandler.ValidateToken() (δεν είναι σίγουρος ποια ακριβώς έκδοση που χρησιμοποιείτε, αλλά νομίζω ότι το μήνυμα είναι το ίδιο), φαίνεται ότι «είναι κρυπτογραφημένη» είναι απλά αποφάσισε όπως «έχει 5 μέρη για να», η οποία θα πρέπει είναι εύκολο να εφαρμοστεί (copy / paste) στο νέο διαχειριστή σας.

Απαντήθηκε 27/11/2018 στις 19:27
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more