{"action":"created","comment":{"url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/comments/43021896","id":43021896,"diff_hunk":"@@ -1625,97 +1649,235 @@ internal partial class OpenIdConnectServerHandler : AuthenticationHandler<OpenId\n                     RequestType = OpenIdConnectRequestType.AuthenticationRequest\n                 };\n             }\n-            \n-            AuthenticationTicket ticket;\n-            if (!string.IsNullOrEmpty(request.AccessToken)) {\n-                ticket = await ReceiveAccessTokenAsync(request.AccessToken, request);\n-            }\n-\n-            else if (!string.IsNullOrEmpty(request.IdToken)) {\n-                ticket = await ReceiveIdentityTokenAsync(request.IdToken, request);\n-            }\n-\n-            else if (!string.IsNullOrEmpty(request.GetRefreshToken())) {\n-                ticket = await ReceiveRefreshTokenAsync(request.GetRefreshToken(), request);\n-            }\n \n-            else {\n-                await SendErrorPayloadAsync(new OpenIdConnectMessage {\n+            if (string.IsNullOrWhiteSpace(request.Token))\n+            {\n+                await SendErrorPayloadAsync(new OpenIdConnectMessage\n+                {\n                     Error = OpenIdConnectConstants.Errors.InvalidRequest,\n-                    ErrorDescription = \"A malformed validation request has been received: \" +\n-                        \"either an identity token, an access token or a refresh token must be provided.\"\n+                    ErrorDescription = \"A malformed introspection request has been received: \" +\n+                        \"a 'token' parameter with an access, refresh, or id token is required.\"\n                 });\n \n                 return;\n             }\n \n-            if (ticket == null) {\n-                Options.Logger.WriteError(\"invalid token\");\n+            //TODO: Re-examine authentication logic to ensure authentication happens in some way.\n+            //TODO: Allow extensibility to skip authentication somehow for access tokens.\n+            //      Perhaps in Options.Provider.ValidationEndpoint()?\n+            // Attempt to Recieve an Access Token for authentication\n+            // See https://tools.ietf.org/html/rfc7662#section-2.1\n+            var authTicket = await ReceiveAccessTokenAsync(request.Token, request);\n+\n+            // If the access token could not be recieved or the ticket could not be parsed,\n+            // Attempt to validate based on client credentials\n+            if(authTicket == null){\n+                var clientNotification = new ValidateClientAuthenticationContext(Context, Options, request);\n+                await Options.Provider.ValidateClientAuthentication(clientNotification);\n+    \n+                // Reject the request if client authentication was rejected.\n+                if (!clientNotification.IsValidated)\n+                {\n+                    Options.Logger.WriteError(\"invalid client authentication.\");\n+    \n+                    await SendErrorPayloadAsync(new OpenIdConnectMessage\n+                    {\n+                        Error = clientNotification.Error ?? OpenIdConnectConstants.Errors.InvalidClient,\n+                        ErrorDescription = clientNotification.ErrorDescription,\n+                        ErrorUri = clientNotification.ErrorUri\n+                    });\n+    \n+                    return;\n+                }\n+    \n+                // Reject if client authentication was skipped.\n+                if (clientNotification.IsSkipped && request.IsClientCredentialsGrantType())\n+                {\n+                    Options.Logger.WriteError(\"client authentication is required for client_credentials grant type.\");\n+    \n+                    await SendErrorPayloadAsync(new OpenIdConnectMessage\n+                    {\n+                        Error = OpenIdConnectConstants.Errors.InvalidGrant,\n+                        ErrorDescription = \"client authentication is required when using client_credentials\"\n+                    });\n+    \n+                    return;\n+                }\n+            }\n \n-                await SendErrorPayloadAsync(new OpenIdConnectMessage {\n-                    Error = OpenIdConnectConstants.Errors.InvalidGrant,\n-                    ErrorDescription = \"Invalid access token received\"\n-                });\n+            // Note: use the token_type_hint parameter to look up a token\n+            // See https://tools.ietf.org/html/rfc7662#section-2.1\n+            AuthenticationTicket ticket = null;\n+            string hint;\n+            if (request.Parameters.TryGetValue(OpenIdConnectConstants.Parameters.TokenTypeHint, out hint))\n+            {\n+                switch (hint)\n+                {\n+                    case OpenIdConnectConstants.TokenHintTypes.AccessToken:\n+                        ticket = await ReceiveAccessTokenAsync(request.Token, request);\n+                        break;\n+                    case OpenIdConnectConstants.TokenHintTypes.RefreshToken:\n+                        ticket = await ReceiveRefreshTokenAsync(request.Token, request);\n+                        break;\n+                    case OpenIdConnectConstants.TokenHintTypes.IdToken:\n+                        ticket = await ReceiveIdentityTokenAsync(request.Token, request);\n+                        break;\n+                }\n+            }\n \n-                return;\n+            // Note: if the coken can't be found using the hint or hint is not sent, search all supported token types.\n+            // See https://tools.ietf.org/html/rfc7662#section-2.1\n+            if (ticket == null)\n+            {\n+                ticket = await ReceiveAccessTokenAsync(request.Token, request);\n+                if (ticket != null)\n+                {\n+                    hint = OpenIdConnectConstants.TokenHintTypes.AccessToken;\n+                }\n+                else\n+                {\n+                    ticket = await ReceiveIdentityTokenAsync(request.Token, request);\n+                    if (ticket != null)\n+                    {\n+                        hint = OpenIdConnectConstants.TokenHintTypes.IdToken;\n+                    }\n+                    else\n+                    {\n+                        ticket = await ReceiveRefreshTokenAsync(request.Token, request);\n+                        if (ticket != null)\n+                        {\n+                            hint = OpenIdConnectConstants.TokenHintTypes.RefreshToken;\n+                        }\n+                    }\n+                }\n             }\n \n-            if (!ticket.Properties.ExpiresUtc.HasValue ||\n-                 ticket.Properties.ExpiresUtc < Options.SystemClock.UtcNow) {\n-                Options.Logger.WriteError(\"expired token\");\n+            ////TODO: Rework this code so it handles the token given in the parameter and NOT\n+            ////  the token given for authentication.\n+            var payload = new JObject();\n+            if (ticket == null)\n+            {\n+                Options.Logger.WriteVerbose(\"invalid token\");\n+                //Handles cases when the request is valid but token is invalid or not deserialized into a ticket\n+                payload.Add(\"active\", false);\n+            }\n+            else\n+            {\n+                // TODO: Determine if this is still valid since requests to the endpoint \"must\" be authenticated/authorized\n+                // Client applications and resource servers are strongly encouraged\n+                // to provide an audience parameter to mitigate confused deputy attacks.\n+                // See http://en.wikipedia.org/wiki/Confused_deputy_problem.\n+                var audiences = ticket.Properties.GetAudiences();\n+                if (audiences.Any() && !audiences.ContainsSet(request.GetAudiences()))\n+                {\n+                    await SendErrorPayloadAsync(new OpenIdConnectMessage\n+                    {\n+                        Error = OpenIdConnectConstants.Errors.InvalidGrant,\n+                        ErrorDescription = \"Invalid access token received: \" +\n+                            \"the audience doesn't correspond to the registered value\"\n+                    });\n \n-                await SendErrorPayloadAsync(new OpenIdConnectMessage {\n-                    Error = OpenIdConnectConstants.Errors.InvalidGrant,\n-                    ErrorDescription = \"Expired access token received\"\n-                });\n+                    return;\n+                }\n \n-                return;\n-            }\n+                var endpointContext = new ValidationEndpointContext(Context, Options, request, ticket);\n \n-            // Client applications and resource servers are strongly encouraged\n-            // to provide an audience parameter to mitigate confused deputy attacks.\n-            // See http://en.wikipedia.org/wiki/Confused_deputy_problem.\n-            var audiences = ticket.Properties.GetAudiences();\n-            if (audiences.Any() && !audiences.ContainsSet(request.GetAudiences())) {\n-                await SendErrorPayloadAsync(new OpenIdConnectMessage {\n-                    Error = OpenIdConnectConstants.Errors.InvalidGrant,\n-                    ErrorDescription = \"Invalid access token received: \" +\n-                        \"the audience doesn't correspond to the registered value\"\n-                });\n+                // Add the claims extracted from the access token.\n+                foreach (var claim in ticket.Identity.Claims)\n+                {\n+                    endpointContext.Claims.Add(claim);\n+                }\n \n-                return;\n-            }\n+                await Options.Provider.ValidationEndpoint(endpointContext);\n \n-            var notification = new ValidationEndpointContext(Context, Options, request, ticket);\n+                // Flow the changes made to the authentication ticket.\n+                ticket = endpointContext.AuthenticationTicket;\n \n-            // Add the claims extracted from the access token.\n-            foreach (var claim in ticket.Identity.Claims) {\n-                notification.Claims.Add(claim);\n-            }\n+                if (endpointContext.HandledResponse)\n+                {\n+                    return;\n+                }\n \n-            await Options.Provider.ValidationEndpoint(notification);\n+                if (ticket.Properties.ExpiresUtc.HasValue && ticket.Properties.ExpiresUtc < Options.SystemClock.UtcNow)\n+                {\n+                    Options.Logger.WriteVerbose(\"expired token\");\n+                    payload.Add(\"active\", false);\n+                }\n \n-            // Flow the changes made to the authentication ticket.\n-            ticket = notification.AuthenticationTicket;\n+                //TODO: do more testing for token validity.\n \n-            if (notification.HandledResponse) {\n-                return;\n-            }\n+                else\n+                {\n+                    payload.Add(OpenIdConnectConstants.Claims.Active, true);\n \n-            var payload = new JObject();\n+                    var scopes = ticket.GetScopes();\n+                    if (scopes.Any())\n+                    {\n+                        payload.Add(OpenIdConnectConstants.Claims.Scope, string.Join(\" \", scopes));\n+                    }\n+                    \n+                    payload.Add(OpenIdConnectConstants.Claims.ClientId, request.ClientId);\n+\n+                    // TODO: Re-examine whether ticket.Identity will always be the resource owner who authorized the token\n+                    // and whether Username should always be returned\n+                    payload.Add(OpenIdConnectConstants.Claims.Username, ticket.Identity.Name);\n+\n+                    // TODO: Determine the token type for the given token when not an access token\n+                    // See https://tools.ietf.org/html/rfc7662#section-2.2 and https://tools.ietf.org/html/rfc6749#section-5.1\n+                    if (hint.Equals(OpenIdConnectConstants.TokenHintTypes.AccessToken))\n+                    {\n+                        payload.Add(OpenIdConnectConstants.Claims.TokenType, \"Bearer\");\n+                    }\n \n-            payload.Add(\"audiences\", JArray.FromObject(ticket.Properties.GetAudiences()));\n-            payload.Add(\"expires_in\", ticket.Properties.ExpiresUtc.Value);\n-            \n-            payload.Add(\"claims\", JArray.FromObject(\n-                from claim in notification.Claims\n-                select new { type = claim.Type, value = claim.Value }\n-            ));\n+                    if (ticket.Properties.ExpiresUtc.HasValue)\n+                    {\n+                        payload.Add(JwtRegisteredClaimNames.Exp, ticket.Properties.ExpiresUtc.Value.Ticks);","path":"src/Owin.Security.OpenIdConnect.Server/OpenIdConnectServerHandler.Endpoints.cs","position":365,"original_position":365,"commit_id":"ac4a0a93d8be47a0247d194c02d477c10c0f9252","original_commit_id":"ac4a0a93d8be47a0247d194c02d477c10c0f9252","user":{"login":"MonkeyJamboree","id":1505322,"avatar_url":"https://avatars.githubusercontent.com/u/1505322?v=3","gravatar_id":"","url":"https://api.github.com/users/MonkeyJamboree","html_url":"https://github.com/MonkeyJamboree","followers_url":"https://api.github.com/users/MonkeyJamboree/followers","following_url":"https://api.github.com/users/MonkeyJamboree/following{/other_user}","gists_url":"https://api.github.com/users/MonkeyJamboree/gists{/gist_id}","starred_url":"https://api.github.com/users/MonkeyJamboree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MonkeyJamboree/subscriptions","organizations_url":"https://api.github.com/users/MonkeyJamboree/orgs","repos_url":"https://api.github.com/users/MonkeyJamboree/repos","events_url":"https://api.github.com/users/MonkeyJamboree/events{/privacy}","received_events_url":"https://api.github.com/users/MonkeyJamboree/received_events","type":"User","site_admin":false},"body":"Ah, I was unaware. I am a bit shaky on converting to/from `DateTimeOffset` as `AuthenticationTicket.Properties.IssuedUtc` and `AuthenticationTicket.Properties.ExpiresUtc` are. Can I just create a new `DateTime` from the ticks then use `EpochTime.GetIntDate()` for this?","created_at":"2015-10-26T17:07:45Z","updated_at":"2015-10-26T17:07:45Z","html_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pull/152#discussion_r43021896","pull_request_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152","_links":{"self":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/comments/43021896"},"html":{"href":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pull/152#discussion_r43021896"},"pull_request":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152"}}},"pull_request":{"url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152","id":48759022,"html_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pull/152","diff_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pull/152.diff","patch_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pull/152.patch","issue_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/152","number":152,"state":"open","locked":false,"title":"Comments and suggestions for Introspection codebase","user":{"login":"MonkeyJamboree","id":1505322,"avatar_url":"https://avatars.githubusercontent.com/u/1505322?v=3","gravatar_id":"","url":"https://api.github.com/users/MonkeyJamboree","html_url":"https://github.com/MonkeyJamboree","followers_url":"https://api.github.com/users/MonkeyJamboree/followers","following_url":"https://api.github.com/users/MonkeyJamboree/following{/other_user}","gists_url":"https://api.github.com/users/MonkeyJamboree/gists{/gist_id}","starred_url":"https://api.github.com/users/MonkeyJamboree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MonkeyJamboree/subscriptions","organizations_url":"https://api.github.com/users/MonkeyJamboree/orgs","repos_url":"https://api.github.com/users/MonkeyJamboree/repos","events_url":"https://api.github.com/users/MonkeyJamboree/events{/privacy}","received_events_url":"https://api.github.com/users/MonkeyJamboree/received_events","type":"User","site_admin":false},"body":"I finished the initial implementation of the introspection spec. There are several points for possible improvement and optional things that should be implemented at some point or another. I'd like a review and some feedback before proceeding further with it.","created_at":"2015-10-26T16:02:15Z","updated_at":"2015-10-26T17:07:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2a0d023d90a2155ce398f1a665393962da3a5b20","assignee":{"login":"PinpointTownes","id":6998306,"avatar_url":"https://avatars.githubusercontent.com/u/6998306?v=3","gravatar_id":"","url":"https://api.github.com/users/PinpointTownes","html_url":"https://github.com/PinpointTownes","followers_url":"https://api.github.com/users/PinpointTownes/followers","following_url":"https://api.github.com/users/PinpointTownes/following{/other_user}","gists_url":"https://api.github.com/users/PinpointTownes/gists{/gist_id}","starred_url":"https://api.github.com/users/PinpointTownes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PinpointTownes/subscriptions","organizations_url":"https://api.github.com/users/PinpointTownes/orgs","repos_url":"https://api.github.com/users/PinpointTownes/repos","events_url":"https://api.github.com/users/PinpointTownes/events{/privacy}","received_events_url":"https://api.github.com/users/PinpointTownes/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/milestones/3","html_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/milestones/1.0.0-beta4","labels_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/milestones/3/labels","id":1246651,"number":3,"title":"1.0.0-beta4","description":"","creator":{"login":"PinpointTownes","id":6998306,"avatar_url":"https://avatars.githubusercontent.com/u/6998306?v=3","gravatar_id":"","url":"https://api.github.com/users/PinpointTownes","html_url":"https://github.com/PinpointTownes","followers_url":"https://api.github.com/users/PinpointTownes/followers","following_url":"https://api.github.com/users/PinpointTownes/following{/other_user}","gists_url":"https://api.github.com/users/PinpointTownes/gists{/gist_id}","starred_url":"https://api.github.com/users/PinpointTownes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PinpointTownes/subscriptions","organizations_url":"https://api.github.com/users/PinpointTownes/orgs","repos_url":"https://api.github.com/users/PinpointTownes/repos","events_url":"https://api.github.com/users/PinpointTownes/events{/privacy}","received_events_url":"https://api.github.com/users/PinpointTownes/received_events","type":"User","site_admin":false},"open_issues":7,"closed_issues":9,"state":"open","created_at":"2015-08-08T18:06:59Z","updated_at":"2015-10-26T16:34:42Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152/commits","review_comments_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152/comments","review_comment_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/152/comments","statuses_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/statuses/ac4a0a93d8be47a0247d194c02d477c10c0f9252","head":{"label":"MonkeyJamboree:Features/dev/Introspection","ref":"Features/dev/Introspection","sha":"ac4a0a93d8be47a0247d194c02d477c10c0f9252","user":{"login":"MonkeyJamboree","id":1505322,"avatar_url":"https://avatars.githubusercontent.com/u/1505322?v=3","gravatar_id":"","url":"https://api.github.com/users/MonkeyJamboree","html_url":"https://github.com/MonkeyJamboree","followers_url":"https://api.github.com/users/MonkeyJamboree/followers","following_url":"https://api.github.com/users/MonkeyJamboree/following{/other_user}","gists_url":"https://api.github.com/users/MonkeyJamboree/gists{/gist_id}","starred_url":"https://api.github.com/users/MonkeyJamboree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MonkeyJamboree/subscriptions","organizations_url":"https://api.github.com/users/MonkeyJamboree/orgs","repos_url":"https://api.github.com/users/MonkeyJamboree/repos","events_url":"https://api.github.com/users/MonkeyJamboree/events{/privacy}","received_events_url":"https://api.github.com/users/MonkeyJamboree/received_events","type":"User","site_admin":false},"repo":{"id":43457262,"name":"AspNet.Security.OpenIdConnect.Server","full_name":"MonkeyJamboree/AspNet.Security.OpenIdConnect.Server","owner":{"login":"MonkeyJamboree","id":1505322,"avatar_url":"https://avatars.githubusercontent.com/u/1505322?v=3","gravatar_id":"","url":"https://api.github.com/users/MonkeyJamboree","html_url":"https://github.com/MonkeyJamboree","followers_url":"https://api.github.com/users/MonkeyJamboree/followers","following_url":"https://api.github.com/users/MonkeyJamboree/following{/other_user}","gists_url":"https://api.github.com/users/MonkeyJamboree/gists{/gist_id}","starred_url":"https://api.github.com/users/MonkeyJamboree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MonkeyJamboree/subscriptions","organizations_url":"https://api.github.com/users/MonkeyJamboree/orgs","repos_url":"https://api.github.com/users/MonkeyJamboree/repos","events_url":"https://api.github.com/users/MonkeyJamboree/events{/privacy}","received_events_url":"https://api.github.com/users/MonkeyJamboree/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server","description":"OWIN/Katana and ASP.NET 5-based OpenID Connect/OAuth2 server","fork":true,"url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server","forks_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/forks","keys_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/teams","hooks_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/hooks","issue_events_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/issues/events{/number}","events_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/events","assignees_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/assignees{/user}","branches_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/branches{/branch}","tags_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/tags","blobs_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/git/refs{/sha}","trees_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/statuses/{sha}","languages_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/languages","stargazers_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/stargazers","contributors_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/contributors","subscribers_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/subscribers","subscription_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/subscription","commits_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/commits{/sha}","git_commits_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/git/commits{/sha}","comments_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/comments{/number}","issue_comment_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/issues/comments{/number}","contents_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/contents/{+path}","compare_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/merges","archive_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/downloads","issues_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/issues{/number}","pulls_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/pulls{/number}","milestones_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/milestones{/number}","notifications_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/labels{/name}","releases_url":"https://api.github.com/repos/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server/releases{/id}","created_at":"2015-09-30T20:29:06Z","updated_at":"2015-09-30T20:29:07Z","pushed_at":"2015-10-26T14:41:11Z","git_url":"git://github.com/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server.git","ssh_url":"git@github.com:MonkeyJamboree/AspNet.Security.OpenIdConnect.Server.git","clone_url":"https://github.com/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server.git","svn_url":"https://github.com/MonkeyJamboree/AspNet.Security.OpenIdConnect.Server","homepage":"","size":2648,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"vNext"}},"base":{"label":"aspnet-contrib:dev","ref":"dev","sha":"8d6cd5eb93f313d23e9160d231124c3ba43ea955","user":{"login":"aspnet-contrib","id":7998081,"avatar_url":"https://avatars.githubusercontent.com/u/7998081?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet-contrib","html_url":"https://github.com/aspnet-contrib","followers_url":"https://api.github.com/users/aspnet-contrib/followers","following_url":"https://api.github.com/users/aspnet-contrib/following{/other_user}","gists_url":"https://api.github.com/users/aspnet-contrib/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet-contrib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet-contrib/subscriptions","organizations_url":"https://api.github.com/users/aspnet-contrib/orgs","repos_url":"https://api.github.com/users/aspnet-contrib/repos","events_url":"https://api.github.com/users/aspnet-contrib/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet-contrib/received_events","type":"Organization","site_admin":false},"repo":{"id":21247659,"name":"AspNet.Security.OpenIdConnect.Server","full_name":"aspnet-contrib/AspNet.Security.OpenIdConnect.Server","owner":{"login":"aspnet-contrib","id":7998081,"avatar_url":"https://avatars.githubusercontent.com/u/7998081?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet-contrib","html_url":"https://github.com/aspnet-contrib","followers_url":"https://api.github.com/users/aspnet-contrib/followers","following_url":"https://api.github.com/users/aspnet-contrib/following{/other_user}","gists_url":"https://api.github.com/users/aspnet-contrib/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet-contrib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet-contrib/subscriptions","organizations_url":"https://api.github.com/users/aspnet-contrib/orgs","repos_url":"https://api.github.com/users/aspnet-contrib/repos","events_url":"https://api.github.com/users/aspnet-contrib/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet-contrib/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server","description":"OWIN/Katana and ASP.NET 5-based OpenID Connect/OAuth2 server","fork":false,"url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server","forks_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/forks","keys_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/teams","hooks_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/hooks","issue_events_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/events","assignees_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tags","blobs_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/languages","stargazers_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/stargazers","contributors_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/contributors","subscribers_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/subscribers","subscription_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/subscription","commits_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/merges","archive_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/downloads","issues_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/labels{/name}","releases_url":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/releases{/id}","created_at":"2014-06-26T16:41:28Z","updated_at":"2015-10-24T04:13:36Z","pushed_at":"2015-10-26T16:02:15Z","git_url":"git://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server.git","ssh_url":"git@github.com:aspnet-contrib/AspNet.Security.OpenIdConnect.Server.git","clone_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server.git","svn_url":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server","homepage":"","size":8725,"stargazers_count":56,"watchers_count":56,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":26,"mirror_url":null,"open_issues_count":11,"forks":26,"open_issues":11,"watchers":56,"default_branch":"vNext"}},"_links":{"self":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152"},"html":{"href":"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pull/152"},"issue":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/152"},"comments":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/152/comments"},"review_comments":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152/comments"},"review_comment":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/pulls/152/commits"},"statuses":{"href":"https://api.github.com/repos/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/statuses/ac4a0a93d8be47a0247d194c02d477c10c0f9252"}}}}