Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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();
        }
Beispiel #12
0
        private async Task <UserPreference> GetEntity()
        {
            var userId = JwtReader.GetUserId();

            return(await Repository.FirstOrDefaultAsync(up => up.UserId == userId));
        }