static void Main() { // This sample demonstrates how to validate a token that may come form different issuers. // This is common if you have to support multiple Authorization Servers. var keyIssuer1 = new SymmetricJwk("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU"); var policyIssuer1 = new TokenValidationPolicyBuilder() .RequireSignature(keyIssuer1, SignatureAlgorithm.HmacSha256) .RequireAudience("636C69656E745F6964") .RequireIssuer("https://idp1.example.com/") .Build(); var keyIssuer2 = new SymmetricJwk("9dobXhxMWH9PoLsKRdv1qp0bEqJm4YNd8JRaTxes8i4"); var policyIssuer2 = new TokenValidationPolicyBuilder() .RequireSignature(keyIssuer2, SignatureAlgorithm.HmacSha256) .RequireAudience("9656E745F6964636C6") .RequireIssuer("https://idp2.example.com/") .Build(); var keyIssuer3 = new SymmetricJwk("lh2TJcMdPyNLhfNp0nYLAFM_R0UEXVoZ9N7ife4ZT-A"); var policyIssuer3 = new TokenValidationPolicyBuilder() .RequireSignature(keyIssuer3, SignatureAlgorithm.HmacSha256) .RequireAudience("F6964636C69656E745") .RequireIssuer("https://idp3.example.com/") .Build(); var policies = new[] { policyIssuer1, policyIssuer2, policyIssuer3 }; var reader = new JwtReader(); var token = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDAwMDcyMDAsImlhdCI6MjAwMDAwNzIwMCwiaXNzIjoiaHR0cHM6Ly9pZHAzLmV4YW1wbGUuY29tLyIsImF1ZCI6IkY2OTY0NjM2QzY5NjU2RTc0NSJ9.a6RiTht8kyTDL9SZVX9kUye7dJL9YSZxJPbAyaaw3QE"; for (int i = 0; i < policies.Length; i++) { // Try to read the token with the different policies var result = reader.TryReadToken(token, policies[i]); if (result.Succedeed) { Console.WriteLine($"The token is issued by '{result.Token.Issuer}':"); Console.WriteLine(result.Token); break; } Console.WriteLine($"Failed to read the token for the issuer '{policies[i].RequiredIssuer}'."); Console.WriteLine(" Reason: " + result.Status); } }
public async Task <PagedResultOutput <EditorDocument> > GetAllFromUser(Guid userId, PagedResultInput input) { var isOwnUser = JwtReader.GetUserId() == userId; var query = Repository .Where(r => r.UserId == userId) .WhereIf(!isOwnUser, r => r.DocumentAccess == EditorDocumentAllowedAccess.Public) .WhereIf(!string.IsNullOrEmpty(input.Filter), r => r.Title.Contains(input.Filter) || r.Description.Contains(input.Filter)); var totalCount = await query.CountAsync(); var items = await query .Skip(input.SkipCount ?? 0) .Take(input.PageSize ?? 20) .ToListAsync(); return(new PagedResultOutput <EditorDocument>(items, totalCount)); }
private async Task <string> GenerateDocumentTitle() { var output = ""; var currentIndex = 1; while (string.IsNullOrEmpty(output)) { const string titlePrefix = "Novo Documento"; var title = $"{titlePrefix} {currentIndex}"; if (await Repository.AnyAsync(e => e.UserId == JwtReader.GetUserId(true) && e.Title == title)) { currentIndex++; continue; } output = title; } return(output); }
public async Task <UserPreferenceOutput> Create([FromBody] UserPreferenceInput input) { var userId = JwtReader.GetUserId(); var userPreference = Mapper.Map <UserPreference>(input); userPreference.UserId = userId; if (userPreference.InvisibleMode) { await SetAllDocumentsAsPrivate(userId); } var result = await Repository.AddAsync(userPreference); await Context.SaveChangesAsync(); var output = Mapper.Map <UserPreferenceOutput>(result.Entity); return(output); }
static void Main() { var key = new SymmetricJwk("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU"); var policy = new TokenValidationPolicyBuilder() .RequireSignature(key, SignatureAlgorithm.HmacSha256) .RequireAudience("636C69656E745F6964") .RequireIssuer("https://idp.example.com/") .Build(); var reader = new JwtReader(); var result = reader.TryReadToken("eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDAwMDcyMDAsImlhdCI6MjAwMDAwNzIwMCwiaXNzIjoiaHR0cHM6Ly9pZHAuZXhhbXBsZS5jb20vIiwiYXVkIjoiNjM2QzY5NjU2RTc0NUY2OTY0In0.YrrT1Ddp1ampsDd2GwYZoTz_bUnLt_h--f16wsWBedk", policy); if (result.Succedeed) { Console.WriteLine("The token is " + result.Token); } else { Console.WriteLine("Failed to read the token. Reason: " + Environment.NewLine + result.Status); } }
public void Write_Binary() { var data = new byte[256]; FillData(data); var key = new RsaJwk ( n: "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1WlUzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDprecbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBIY2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw", e: "AQAB", d: "VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-rynq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-KyvjT1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ", p: "9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEPkrdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM", q: "uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-yBhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0", dp: "w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuvngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcraHawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs", dq: "o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU", qi: "eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlCtUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZB9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo" ) { Alg = KeyManagementAlgorithm.RsaPkcs1.Utf8Name }; var descriptor = new BinaryJweDescriptor(data); descriptor.EncryptionKey = key; descriptor.EncryptionAlgorithm = EncryptionAlgorithm.Aes128CbcHmacSha256; descriptor.Algorithm = KeyManagementAlgorithm.RsaPkcs1; JwtWriter writer = new JwtWriter(); var value = writer.WriteToken(descriptor); Assert.NotNull(value); var reader = new JwtReader(key); var result = reader.TryReadToken(value, TokenValidationPolicy.NoValidation); Assert.Equal(TokenValidationStatus.Success, result.Status); var jwt = result.Token; Assert.Equal(data, jwt.Binary); }
public void Write_Utf8ToEscape() { var plaintext = "Live long and prosper!€"; var descriptor = new PlaintextJweDescriptor(plaintext); descriptor.EncryptionKey = RsaKey; descriptor.EncryptionAlgorithm = EncryptionAlgorithm.Aes128CbcHmacSha256; descriptor.Algorithm = KeyManagementAlgorithm.RsaPkcs1; JwtWriter writer = new JwtWriter(); var value = writer.WriteToken(descriptor); var reader = new JwtReader(RsaKey); var result = reader.TryReadToken(value, TokenValidationPolicy.NoValidation); Assert.Equal(TokenValidationStatus.Success, result.Status); var jwt = result.Token; Assert.Equal(plaintext, jwt.Plaintext); }
public async Task Denounce([FromBody] DenounceInput input) { var userId = JwtReader.GetUserId(false); var hasUserAlreadyDenounce = await HasUserAlreadyDenounce(input.DocumentId, input.DenounceMotivation, userId); if (hasUserAlreadyDenounce) { return; } await Repository.AddAsync(new DenounceDocument { DocumentId = input.DocumentId, DenounceMotivation = input.DenounceMotivation, Description = input.Description, UserId = userId == Guid.Empty ? (Guid?)null : userId, DenounceTime = DateTime.Now }); await Context.SaveChangesAsync(); await CheckForBlockDocument(input.DocumentId, input.DenounceMotivation); }
public void Encode_Decode(string alg) { var(signingKey, validationKey) = SelectKeys(alg); var writer = new JwtWriter(); var descriptor = new JwsDescriptor { SigningKey = signingKey, Algorithm = (SignatureAlgorithm)alg, Subject = "Alice" }; var token = writer.WriteToken(descriptor); var reader = new JwtReader(); var policy = new TokenValidationPolicyBuilder() .RequireSignature(validationKey, (SignatureAlgorithm)alg) .Build(); var result = reader.TryReadToken(token, policy); Assert.Equal(TokenValidationStatus.Success, result.Status); Assert.Equal("Alice", result.Token.Subject); }
public async Task <EditorDocument> Create(DocumentCreateOrUpdateInput input) { var itemToInsert = Mapper.Map <EditorDocument>(input); if (string.IsNullOrEmpty(itemToInsert.Title)) { itemToInsert.Title = await GenerateDocumentTitle(); } else { var hasSameTitleDocument = await HasSameTitleDocument(itemToInsert.Title); if (hasSameTitleDocument) { Response.StatusCode = (int)HttpStatusCode.Conflict; return(null); } } itemToInsert.UserId = JwtReader.GetUserId(); if (input.Tags != null) { itemToInsert.Tags = input.Tags.Select(t => { t.TagName = t.TagName.ToLower(); return(t); }).ToList(); } itemToInsert.DocumentAccess ??= EditorDocumentAllowedAccess.Private; itemToInsert.CreationTime = DateTime.Now; var item = await Repository.AddAsync(itemToInsert); await Context.SaveChangesAsync(); return(item.Entity); }
private void NewConnectionHandler() { var server = new TcpListener(ip, port); server.Start(); var policy = new TokenValidationPolicyBuilder() .RequireSignature(SymmetricJwk.FromBase64Url(confWebSocket.JwsKey), SignatureAlgorithm.HmacSha512) .RequireIssuer("Leierkasten Backend") .Build(); var reader = new JwtReader(); while (running) { TcpClient client; if (server.Pending()) { client = server.AcceptTcpClient(); } else { Thread.Sleep(100); continue; } var stream = client.GetStream(); stream.WriteTimeout = 10; while (client.Available < 3) { Thread.Sleep(100); } var bytes = new byte[client.Available]; stream.Read(bytes, 0, bytes.Length); // This is a textual request, decode it var request = Encoding.UTF8.GetString(bytes); // Check if this is a websocket handshake. If no, skip. if (!new Regex("^GET").IsMatch(request)) { Log.Warn("Denied websocket because client used wrong method."); stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length); continue; } const string eol = "\r\n"; const string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // HTML headers are case insensitive var match = new Regex("Sec-WebSocket-Key: (.*)", RegexOptions.IgnoreCase).Match(request); if (!match.Success) { Log.Warn("Sec-WebSocket-Key was not found in request."); Log.Trace("Request was (base64-encoded): " + Convert.ToBase64String(Encoding.ASCII.GetBytes(request))); stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length); continue; } if (match.Groups.Count != 2) { InvalidMatchNumber(match, stream); continue; } string key = match.Groups[1].Value.Trim(); byte[] hashedAcceptKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key + guid)); string base64AcceptKey = Convert.ToBase64String(hashedAcceptKey); Log.Trace("Received Sec-WebSocket-Key: " + key); if (Log.IsTraceEnabled) { StringBuilder hex = new StringBuilder(hashedAcceptKey.Length * 2); foreach (byte b in hashedAcceptKey) { hex.AppendFormat("{0:x2}", b); } Log.Trace("Hashed Sec-WebSocket-Key: " + hex); } Log.Trace("Base64 if Sec-WebSocket-Key Hash: " + base64AcceptKey); string responseStr = "HTTP/1.1 101 Switching Protocols" + eol + "Connection: Upgrade" + eol + "Upgrade: websocket" + eol + "Sec-WebSocket-Accept: " + base64AcceptKey + eol + eol; byte[] response = Encoding.UTF8.GetBytes(responseStr); // Get cookie match = new Regex("lk-session=([^;\r\n]*)", RegexOptions.IgnoreCase).Match(request); if (!match.Success) { Log.Warn("Denied websocket because session cookie is missing."); stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length); continue; } if (match.Groups.Count != 2) { InvalidMatchNumber(match, stream); continue; } // Validate session cookie of user var sessionCookie = match.Groups[1].ToString(); var result = reader.TryReadToken(sessionCookie, policy); if (!result.Succedeed) { Log.Warn($"Denied websocket because JWS token could not be validated: {result.ErrorHeader}, {result.ErrorClaim}."); stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length); continue; } if (result.Token?.Payload == null) { Log.Warn("Denied websocket because JWS token payload is empty."); stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length); continue; } var uid = JsonConvert.DeserializeObject <Dictionary <string, string> >(result.Token.Payload.ToString())["uid"]; // Send handshake response stream.Write(response, 0, response.Length); // Start handler for the connection var handler = new WebSocketConnection(client, uid); if (!ConnectedClients.TryAdd(clientCounter++, handler)) { handler.Stop(); } else { OnClientConnected?.Invoke(this, new ClientConnectedEventArgs(handler)); } } server.Stop(); }
private async Task <UserPreference> GetEntity() { var userId = JwtReader.GetUserId(); return(await Repository.FirstOrDefaultAsync(up => up.UserId == userId)); }