{"action":"created","issue":{"url":"https://api.github.com/repos/openiddict/core/issues/58","repository_url":"https://api.github.com/repos/openiddict/core","labels_url":"https://api.github.com/repos/openiddict/core/issues/58/labels{/name}","comments_url":"https://api.github.com/repos/openiddict/core/issues/58/comments","events_url":"https://api.github.com/repos/openiddict/core/issues/58/events","html_url":"https://github.com/openiddict/core/issues/58","id":130998688,"number":58,"title":"Cookies and Tokens","user":{"login":"Gillardo","id":7406381,"avatar_url":"https://avatars.githubusercontent.com/u/7406381?v=3","gravatar_id":"","url":"https://api.github.com/users/Gillardo","html_url":"https://github.com/Gillardo","followers_url":"https://api.github.com/users/Gillardo/followers","following_url":"https://api.github.com/users/Gillardo/following{/other_user}","gists_url":"https://api.github.com/users/Gillardo/gists{/gist_id}","starred_url":"https://api.github.com/users/Gillardo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gillardo/subscriptions","organizations_url":"https://api.github.com/users/Gillardo/orgs","repos_url":"https://api.github.com/users/Gillardo/repos","events_url":"https://api.github.com/users/Gillardo/events{/privacy}","received_events_url":"https://api.github.com/users/Gillardo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-02-03T11:35:30Z","updated_at":"2016-02-04T23:41:12Z","closed_at":null,"body":"Just want to say, love this project btw!!  Love the examples as well, although an AngularJs one would be nice, with details on how to use refresh_tokens, but i am sure this will all come with time.\r\n\r\nI am not sure if this is a problem with OpenIddict, or my setup, or if it aint a problem.\r\n\r\nI am using (want to use only) tokens for authentication.  I am sending the tokens with angular, and this works fine i believe.  The problem i am having is that a cookie is being used in my application and this is being sent with my angular requests.  I cannot override this.  So now when users logout of my site (which i just set the token to null), users are really still logged in, because the cookie is on the machine.\r\n\r\nI have added this to my startup.cs to support tokens (as suggested by @PinpointTownes, thank you) \r\n```\r\n// Add a middleware used to validate access tokens and protect the API endpoints.\r\napp.UseOAuthValidation();\r\n```\r\n\r\nI still want to use external providers, and i am guessing an \"external\" cookie must be used for that, so that is fine.  Maybe this is a problem because my authorization server and resource server are on the same domain?  My angular app using Satellizer to open the Account/Login view.  All the code for OpenIddict is basically exactly the same as the Mvc.Server example.  Maybe a better question is, can i exclude cookies for all my api calls?\r\n\r\nHere is my startup.cs file, just encase someone can shed light on something.  Thanks in advance for any help/tips.\r\n\r\n```\r\n    public class Startup\r\n    {\r\n\r\n        public static void Main(string[] args)\r\n        {\r\n            var application = new WebApplicationBuilder()\r\n                .UseConfiguration(WebApplicationConfiguration.GetDefault(args))\r\n                .UseStartup<Startup>()\r\n                .Build();\r\n\r\n            application.Run();\r\n        }\r\n\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            // file is stored above the wwwroot\r\n            var webRootPath = services.BuildServiceProvider()\r\n                .GetRequiredService<IHostingEnvironment>()\r\n                .MapPath(\"../\");\r\n\r\n            // configuration\r\n            var configuration = new ConfigurationBuilder()\r\n                .AddJsonFile(string.Format(\"{0}appsettings.json\", webRootPath))\r\n                .AddEnvironmentVariables()\r\n                .Build();\r\n\r\n            // application settings\r\n            var appSettings = configuration.Get<AppSettings>();\r\n\r\n            // mvc\r\n            services.AddMvc();\r\n\r\n            // ef7\r\n            services.AddEntityFramework()\r\n                .AddSqlServer()\r\n                .AddDbContext<ApplicationDbContext>(options =>\r\n                    options.UseSqlServer(appSettings.Data.AuthConnection.ConnectionString)\r\n                           .UseRowNumberForPaging());\r\n\r\n            // identity\r\n            services.AddIdentity<ApplicationUser, ApplicationUserRole>(config =>\r\n            {\r\n                // if we are accessing the /api and an unauthorized request is made\r\n                // do not redirect to the login page, but simply return \"Unauthorized\"\r\n                config.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents\r\n                {\r\n                    OnRedirectToLogin = ctx =>\r\n                    {\r\n                        if (ctx.Request.Path.StartsWithSegments(\"/api\"))\r\n                            ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;\r\n                        else\r\n                            ctx.Response.Redirect(ctx.RedirectUri);\r\n\r\n                        return System.Threading.Tasks.Task.FromResult(0);\r\n                    }\r\n                };\r\n            })\r\n                .AddEntityFrameworkStores<ApplicationDbContext>()\r\n                .AddDefaultTokenProviders()\r\n                .AddOpenIddict();\r\n\r\n            // dependencies\r\n            // add services here\r\n        }\r\n\r\n        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)\r\n        {\r\n            // loggers\r\n            loggerFactory.AddConsole();\r\n            loggerFactory.AddDebug();\r\n\r\n            // get current appSettings and output to logger\r\n            var appSettings = app.ApplicationServices.GetRequiredService<AppSettings>();\r\n            var logger = loggerFactory.CreateLogger(appSettings.Url);\r\n            logger.LogInformation(string.Format(\"Environment: {0}\", appSettings.Environment));\r\n            logger.LogInformation(string.Format(\"Data: {0}\", appSettings.Data.DefaultConnection.ConnectionString));\r\n            logger.LogInformation(string.Format(\"Auth: {0}\", appSettings.Data.AuthConnection.ConnectionString));\r\n\r\n            // environment\r\n            env.EnvironmentName = appSettings.Environment;\r\n\r\n            if (appSettings.Environment == \"Development\")\r\n                app.UseDeveloperExceptionPage();\r\n\r\n            app.UseIISPlatformHandler(options =>\r\n            {\r\n                options.AuthenticationDescriptions.Clear();\r\n                options.FlowWindowsAuthentication = false;\r\n            });\r\n\r\n            app.UseOverrideHeaders(options =>\r\n            {\r\n                options.ForwardedOptions = ForwardedHeaders.All;\r\n            });\r\n\r\n            app.UseStaticFiles();\r\n\r\n            // Add a middleware used to validate access tokens and protect the API endpoints.\r\n            app.UseOAuthValidation();\r\n\r\n            // comment this out and you get an error saying \r\n            // InvalidOperationException: No authentication handler is configured to handle the scheme: Microsoft.AspNet.Identity.External\r\n            app.UseIdentity();\r\n\r\n            // Add external providers\r\n            if (appSettings.Authentication.Google != null)\r\n                app.UseGoogleAuthentication(options =>\r\n                {\r\n                    options.ClientId = appSettings.Authentication.Google.ClientId;\r\n                    options.ClientSecret = appSettings.Authentication.Google.ClientSecret;\r\n                });\r\n\r\n            // Note: OpenIddict must be added after ASP.NET Identity and the external providers.\r\n            app.UseOpenIddict(builder =>\r\n            {\r\n                // You can customize the default Content Security Policy (CSP) by calling UseNWebsec explicitly.\r\n                // This can be useful to allow your HTML views to reference remote scripts/images/styles.\r\n                builder.UseNWebsec(directives => {\r\n                    directives\r\n                        .DefaultSources(directive => directive.Self())\r\n                        .ImageSources(directive => directive\r\n                            .Self()\r\n                            .CustomSources(\"data:\"))\r\n                        .ScriptSources(directive => directive\r\n                            .Self()\r\n                            .UnsafeInline())\r\n                        .StyleSources(directive => directive\r\n                            .Self()\r\n                            .UnsafeInline()\r\n                            .CustomSources(\"https://fonts.googleapis.com\"))\r\n                        .FontSources(directive => directive\r\n                            .Self()\r\n                            .CustomSources(\"https://fonts.gstatic.com\"));\r\n                });\r\n\r\n                if (appSettings.Environment == \"Development\")\r\n                {\r\n                    builder.Options.AllowInsecureHttp = true;\r\n                }\r\n                else\r\n                {\r\n                    // get thumbprint, remove any spaces\r\n                    var thumbprint = appSettings.Authentication.OpenId.Thumbprint.Replace(\" \", string.Empty);\r\n\r\n                    // add cert\r\n                    builder.Options.SigningCredentials.AddCertificate(thumbprint);\r\n                }\r\n            });\r\n\r\n            // Mvc routes\r\n            app.UseMvc(builder =>\r\n            {\r\n                // default goes to Home, and angular will deal with client side routing\r\n                builder.MapRoute(\r\n                    name: \"default\",\r\n                    template: \"{*url}\",\r\n                    defaults: new { controller = \"home\", action = \"index\" });\r\n            });\r\n\r\n        }\r\n\r\n    }\r\n```"},"comment":{"url":"https://api.github.com/repos/openiddict/core/issues/comments/180105010","html_url":"https://github.com/openiddict/core/issues/58#issuecomment-180105010","issue_url":"https://api.github.com/repos/openiddict/core/issues/58","id":180105010,"user":{"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},"created_at":"2016-02-04T23:41:12Z","updated_at":"2016-02-04T23:41:12Z","body":"The \"issue\" you're seeing is by design and is caused by the fact the cookies middleware added by ASP.NET Identity uses the automatic authentication mode (so when a request arrives, both the cookies middleware and the validation middleware are invoked).\r\n\r\nYou could consider switching to manual authentication, but the recommended approach is to set up an authorization policy restricting the authentication to the bearer scheme. You can directly use [`AuthorizeAttribute`'s `ActiveAuthenticationSchemes` property for that] (https://github.com/openiddict/core/blob/dev/samples/Mvc.Server/Controllers/ResourceController.cs#L9) or create a more complex policy directly at the services level (via `services.AddAuthorization()`)."}}