-
Notifications
You must be signed in to change notification settings - Fork 599
[Draft] Auth 2.0 Migration announcement #1310
Comments
I'm drafting the announcement here, when we are all happy, I'll open the real announcements issue |
Katana => Microsoft.Owin. In 1.0 didn't UseIdentity() need to be before Facebook? Your layout for the 2.0 sample needs work. Is this what the fwlink will point to in the short term? [Authorize] also relies on DefaultAuthenticateScheme. Missing a new line on DefaultForbidScheme. Doesn't DefaultSignOutScheme fall back to SignInScheme? Same for Forbid? |
|
How is this accomplished in 2.0? Example: Also:
The link just takes you to the aspnet core starting page, and I cannot find Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions anywhere. |
@tylerd try |
updated with feedback, not sure what layout issue @Tratcher feel free to fix it directly. Added a placeholder to go over AuthZ changes as well, Authorize deserves a section even tho it hasn't changed that much. |
Updated the indenting |
Added a major section on Authorization/Authorize/ChallengeBehavior |
It looks good, but you should maybe insist on the fact the old stack was not just obsoleted but is now completely unusable. It would be also great to mention that older middleware written for 1.0 will not work and that moving to a 2.0.0-compatible version is mandatory.
What, did you really rename |
@Tratcher can you write the section on host changes for HttpSys/IISIntegration in a comment and I'll merge it? |
@PinpointTownes they don't look the same for one, and I prefer the new name, https://github.com/aspnet/Security/blob/rel/1.1.2/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs vs https://github.com/aspnet/HttpAbstractions/blob/dev/src/Microsoft.AspNetCore.Authentication.Abstractions/IClaimsTransformation.cs |
Buh, the new name is ugly Note that getting rid of |
Other things you should treat:
|
@PinpointTownes well, its just a normal service now which can consume whatever it wants from DI, unlike before, but sure I'll call that out in the claims xform section. Added some text about mixing 1.0 and 2.0 together in the initial section, but this probably needs a longer dedicated section in the known breaking changes when I get to it. re Properties and things moving around, that will go into this placeholder section: Overview of Auth core/scheme provider/request handler section. This announcment is probably going to be really really long (too long I think). Hopefully @Rick-Anderson will turn this into real docs :) |
ChallengeBehavior.Automatic description is backwards, it forbids if you already have a ticket. |
Not much to say for the hosts. The biggest visible differences are that they were each consolidated to a single "Windows" scheme, and that IISIntegration now conditionally registers the handler only if windows auth is enabled in IIS (if you have the latest version of ANCM, otherwise it's always registered as before). |
Cool thanks, added the host section |
Added "New Microsoft.AspNet.Authentication.Core/Abstractions" section |
Needs a sample showing this common scenario:
|
@danroth27 didn't you say that you were able to just always challenge cookie? Or is your scenario different? |
Its also there in the example already: |
Dan's scenario is different, he has a login page. For OAuth/OIDC apps without a login page then you need to specify the default challenge too. |
Updated doc with Security/Authenticationhandler overviews along with a short overview of the context/events methods. |
No, you don't. Policies support writing arbitrary logic. I recommend reading https://docs.microsoft.com/en-us/aspnet/core/security/authorization/ |
@chikien276 I managed to get it working after a bit of struggling (after the post I made). Thanks for the code! |
@davidfowl You mean to get authenticated user without var result = await context.AuthenticateAsync(scheme);
var hasClaim = result.Principal.Claims.Any(...); instead of context.HttpContext.User is this correct? |
That's correct. I wrote an example here #1310 (comment) |
These docs in the below link are out of date, following them presents a deprecated warning when you use https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?tabs=visual-studio |
Ok I seem to have found some migration docs hidden away - https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x |
@davidfowl // add cookie
.AddCookie("scheme1", o =>
{
o.ExpireTimeSpan = TimeSpan.FromSeconds(30);
o.LoginPath = new PathString("/FooUser");
o.Cookie.Name = "token1";
o.SlidingExpiration = true;
})
var result = await HttpContext.AuthenticateAsync("scheme1");
if(result.Succeeded) // if i keep hitting F5 in every second, the authenticate is success. but if i refresh after few second or may be after expire, it expired. Any idea? |
Because you have SlidingExpiration set to true? https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.cookies.cookieauthenticationoptions.slidingexpiration?view=aspnetcore-2.0#Microsoft_AspNetCore_Authentication_Cookies_CookieAuthenticationOptions_SlidingExpiration /cc @Tratcher |
@davidfowl Well, i have set expiration time to 30 second and |
The point of SlidingRefresh is to extend the cookie lifetime as long as the user remains active. When you press F5 the cookie gets renewed if it hasn't expired yet. |
@Tratcher Now i get it. Thanks |
…Startup class to new 2.0 authentication stack (see aspnet/Security#1310)
.net core 2.0 and security changes aspnet/Security#1310
In .NET Core 1.X, we had a JWT token authentication setup that included a TokenController responsible for generating tokens, TokenAuthenticationMiddleware that checks for valid tokens, and an ApiAuthorizeAttribute that we would use on specific controllers/methods to check for specific permissions. In order to get it working with .NET Core 2.0, we did the following. Updated Startup.cs: .NET Core 1.X var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("TokenProviderOptions:SecretKey").Value));
var tokenValidationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = Configuration.GetSection("TokenProviderOptions:Issuer").Value,
ValidateAudience = true,
ValidAudience = Configuration.GetSection("TokenProviderOptions:Audience").Value,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
Audience = Configuration.GetSection("TokenProviderOptions:Audience").Value,
ClaimsIssuer = Configuration.GetSection("TokenProviderOptions:Issuer").Value,
AutomaticAuthenticate = true,
TokenValidationParameters = tokenValidationParameters,
SaveToken = true
}); to .NET Core 2.0 var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("TokenProviderOptions:SecretKey").Value));
var tokenValidationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = Configuration.GetSection("TokenProviderOptions:Issuer").Value,
ValidateAudience = true,
ValidAudience = Configuration.GetSection("TokenProviderOptions:Audience").Value,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Audience = Configuration.GetSection("TokenProviderOptions:Audience").Value;
options.ClaimsIssuer = Configuration.GetSection("TokenProviderOptions:Issuer").Value;
options.TokenValidationParameters = tokenValidationParameters;
options.SaveToken = true;
}); Updated TokenAuthenticationMiddleware .NET Core 1.X public async Task Invoke(HttpContext context, ITraffkTenantFinder traffkTenantFinder)
{
var authenticateInfo = await context.AuthenticateAsync("Bearer");
var bearerTokenIdentity = authenticateInfo?.Principal;
if (bearerTokenIdentity != null)
{
var currentTenantId = traffkTenantFinder.GetTenantIdAsync().ExecuteSynchronously();
var tenantIdClaim = bearerTokenIdentity.Claims.First(x => x.Properties.Values.Contains(JwtRegisteredClaimNames.Sub));
var tenantIdInToken = int.Parse(tenantIdClaim.Value);
if (tenantIdInToken == currentTenantId)
{
await Next(context);
return;
}
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
}
//No bearer token in use, move on
await Next(context);
} to .NET Core 2.0 public async Task Invoke(HttpContext context, ITraffkTenantFinder traffkTenantFinder)
{
var authenticateInfo = await context.AuthenticateAsync("Bearer");
var bearerTokenIdentity = authenticateInfo?.Principal;
if (bearerTokenIdentity != null)
{
var currentTenantId = traffkTenantFinder.GetTenantIdAsync().ExecuteSynchronously();
var tenantIdClaim = bearerTokenIdentity.Claims.First(x => x.Properties.Values.Contains(JwtRegisteredClaimNames.Sub));
var tenantIdInToken = int.Parse(tenantIdClaim.Value);
if (tenantIdInToken == currentTenantId)
{
context.User = bearerTokenIdentity;
await Next(context);
return;
}
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
}
//No bearer token in use, move on
await Next(context);
} nearly identical except for context.User = bearerTokenIdentity; Without this change, we couldn't use context.User which was needed in ApiAuthorizationAttribute. Code for ApiAuthorizeAttribute HandleRequirementAsync below (no changes made during upgrade from 1.X to 2.0): protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ApiRequirement requirement)
{
var claims = context.User.FindAll(c => c.Type == requirement.ClaimType).ToList();
if (claims.Count == 0) return Task.FromResult(0);
foreach (var c in claims)
{
var pcv = PermissionClaimValue.CreateFromJson(c.Value);
if (pcv.Granted)
{
context.Succeed(requirement);
break;
}
}
return Task.FromResult(0);
} And an example of usage of the attribute: [Authorize]
[ApiAuthorize(ApiNames.Base)]
[ApiAuthorize(ApiNames.Rx)]
[Produces("application/json")]
[Route("api/v1")]
public class ExampleApiController : BaseApiController Hope this helps someone out there. |
@HaoK I think the |
Anyone has any ideas on the following? I'm using Cookies and Jwt for different parts of my app, with Cookies being the DefaultAuthenticationScheme. I also have a custom middleware that checks if When authenticating with Cookies everything works. I tried @davidfowl's suggestion of using the |
* Removed some types (moved to lib) * Work in progress * Moved more functionality to ESLib * Removed migration notice (moved to ESLib) * Projects now reference NuGet package "HiP-EventStoreLib" from our MyGet-feed * Now using HiP-EventStoreLib v0.3.0 (class InMemoryCache) * Minor changes * Upgraded projects to .NET Core 2.0, updated HiP-EventStoreLib to 0.6.0 * Update HiP-EventStoreLib to v0.7.0 * Updated dockerfile (now uses .NET Core 2.0 image) * Updated NuGet.Config * Updated docker file * Moved NuGet.Config * Updated dockerfile * Moved NuGet.Config again * Moved MongoDB primitives (DocRef<>) to HiP-EventStoreLib, updated HiP-EventStoreLib to v0.9.0 * Updated NuGet dependencies, migrated authentication configuration in Startup class to new 2.0 authentication stack (see aspnet/Security#1310) * Updated HiP-EventStoreLib to v0.10.0, updated EventStore.ClientAPI.NetCore to v4.0.2-rc * Bugfix for Swagger UI * Added validation of page IDs when creating/updating exhibits * Added validation of audio ID when creating/updating exhibit pages * Bug fix: Timestamp assignment was missing when emitting certain events * Fixed minor merging issues
* Implemented page reordering via PUT /Exhibits/{id}, marked old event types as [Obsolete] * ExhibitResult now makes use of the new Pages property * Fixed a validation bug * Removed unnecessary reference addition * Pages no longer create a reference to the containing exhibit * Simplified exhibit usage checks, reworked the areas that expected Exhibit.Referencees to contain page references (new functionality in ExhibitPageIndex is now used instead) * Added stream metadata class (WIP) * Implemented a new migration concept ("stream migration") that allows versioning of streams. Implemented such a "stream migration" that updates the event stream to support the new page ordering feature. * Fixed: *Update-events were clearing the Referencees-list of the corresponding entity (thus e.g., only the pages created/updated after the latest ExhibitUpdate are shown for the exhibit) * Bug fix in migration * Migration fix * Fixed ReSharper issues * Minor documentation improvement * Added Score Board class * Cleanup of entity classes, more error handling * Added missing [ProducesResponseType(400)] * Hotfix * Hotfix: DocRefList<T> was serialized as array (missing the fields 'Collection' and 'Database') * Fixed a typo which caused the HTTP-route for tag deletion to be malformed (#36) * Hotfix for updating exhibits * Fixed: Whenever updating media, 'File' was set to null * Changes to make pages "independent" from exhibits * Implemented migration * Added a warning when connecting to a production database during a debug session * Added Score Record Added API Calls Fixed Sorting in Score Board * Fixed errors * Fixed R# error Added validation for PUT API call * Removed unused directive * Removed unnesosry return types * Minor clean-up * Added Distinct()-calls to better handle duplicate IDs in JSON request arrays, added field ExhibitPageResult.Used * Events are now emitted in batches by using transactions * Bug fix * Added migration code to make exhibits reference pages * Removed usings * Added removing file from storage (#40) * TagsController.PostAsync now returns "201 Created" instead of "200 Ok", added some documentation * Improved logging * Bugfix in ReferencesIndex * Reverted accidental change in *.DotSettings-file * URL to "swagger.json" file is now configurable * Renamed 'ContentBase.Referencees' to 'Referencers' to better reflect the meaning of that property * HIPCMS-735: Remove status limitations when creating/updating entities (#44) * Removed requirement for referenced entities to be published when creating or updating entities. * Removed unused "using" * HIPCMS-722: Implemented GET-methods for obtaining reference info (#45) * Implemented "GET /api/<resource type>/<id>/Refs"-methods for obtaining reference info (or "usage info") for resources * Added missing [ProducesResponseType(400)] attributes * Removed empty lines * Renamed ReferenceInfoResult properties for less confusion * Added class OrderedSet * DocRefList.Ids is now an ordered set, fixed DocRefExtensions.LoadAll(): now preserves order of IDs * Hipcms 682 (#42) * Added Rating System --Rating system can be aplied to any ResourceType --Added rating to Exhibits * Added minor cleanup * R# Error fixing * R# ResourceType redundance fixing * Added changes: --changed all url form 'rating' to 'Rating' --public fields instead of properties. --changed URL for exhibit/rating * --Added savings of all user`s ratings in memory. --Changed rating type to byte * R# Error fixing * No Storing Ratings in storage Min-Max Rating now can be defined in one place * Added stream migration, added cascading timestamps functionality to ReferencesIndex * Modified controllers to return cascading timestamp instead of "flat" timestamp * CRUD event types can now be excluded from the timestamp cascade mechanism * Minor fix * Fixed a bug * Added Length Parameter to Call (#48) API/ScoreBoard * Completely removed ReferenceAdded/Removed events (necessary for correct timestamp propagation) * Iss hipcms 670 testing (#50) * HIPCMS-670 Project setup and first test. * HIPCMS-670-Tests Tests for tags controller. * HIPCMS-670-Tests-For-Tags * Implemented a very simple mechanism for accessing MVC services in tests (TestStartup makes services available in static MvcTestContext class) * HIPCMS-670 Donw with tags tests * Minor fixes * Improved StreamMigrationArgs: When appending events they are now directly serialized to EventData (to prevent further modifications) * Added a small bug-correcting migration * fix in CorrectExhibitsMigration, reverted some changes of previous commit * Fixed ReSharper warnings * Renamed migrations so its easier to see their order * Removed unnecessary file * Updated some comments * Added "Rank" field in response to API call api/ScoreBoard/{id} (#51) * Added Rank field in response to API call api/ScoreBoard/{id} * Fix R# errors * Iss hipcms 729 (#52) * Updated the webservice lib dependency to 2.0 * Setup auth0 usage * Ignored .vscode folder * Removed the old WebserviceLib dependency * Set up all the controllers to use authorization & fixed a typo in the settings * Implement authorization policies via scopes * add missing library file * renamed to lowercase * Update HiP-DataStore.csproj Test: Set webservice lib version to 1.0.0 * Revert "Update HiP-DataStore.csproj" This reverts commit 72f8f17. * used the public hip feed on myget.org * Removed the webservice lib pkg - will be added via nuget feed on myget.org * Copied nuget config to project root folder * Removed obsolete nuget config and fixed a R# issue * Fixed the docker build by referencing the dockerfile in the root folder * Revert "Iss hipcms 729 (#52)" (#53) This reverts commit c8deab6. * Removed some types (moved to lib) * Clean-up * Clean-up * Clean-up * Bug fix * Bug fixes * Fixed ReSharper warnings * Work in progress * Add long domain to the CORS settings * Moved more functionality to ESLib * Removed migration notice (moved to ESLib) * Projects now reference NuGet package "HiP-EventStoreLib" from our MyGet-feed * Now using HiP-EventStoreLib v0.3.0 (class InMemoryCache) * Iss hipcms 729 (#54) * Updated the webservice lib dependency to 2.0 * Setup auth0 usage * Ignored .vscode folder * Removed the old WebserviceLib dependency * Set up all the controllers to use authorization & fixed a typo in the settings * Implement authorization policies via scopes * add missing library file * renamed to lowercase * Update HiP-DataStore.csproj Test: Set webservice lib version to 1.0.0 * Revert "Update HiP-DataStore.csproj" This reverts commit 72f8f17. * used the public hip feed on myget.org * Removed the webservice lib pkg - will be added via nuget feed on myget.org * Copied nuget config to project root folder * Removed obsolete nuget config and fixed a R# issue * Fixed the docker build by referencing the dockerfile in the root folder * Changed API audience to WebAPI (temp. fix for multiple-audience-problem) * Changed audience and scopes definitions to use the new generic API def. * Minor changes * Upgraded projects to .NET Core 2.0, updated HiP-EventStoreLib to 0.6.0 * Update HiP-EventStoreLib to v0.7.0 * Updated dockerfile (now uses .NET Core 2.0 image) * Updated NuGet.Config * Updated docker file * Moved NuGet.Config * Updated dockerfile * Moved NuGet.Config again * Iss hipcms 667 (#56) * Updated the webservice lib dependency to 2.0 * Setup auth0 usage * Ignored .vscode folder * Removed the old WebserviceLib dependency * Set up all the controllers to use authorization & fixed a typo in the settings * Implement authorization policies via scopes * add missing library file * renamed to lowercase * Update HiP-DataStore.csproj Test: Set webservice lib version to 1.0.0 * Revert "Update HiP-DataStore.csproj" This reverts commit 72f8f17. * used the public hip feed on myget.org * Removed the webservice lib pkg - will be added via nuget feed on myget.org * Copied nuget config to project root folder * Removed obsolete nuget config and fixed a R# issue * Fixed the docker build by referencing the dockerfile in the root folder * Changed API audience to WebAPI (temp. fix for multiple-audience-problem) * Changed audience and scopes definitions to use the new generic API def. * Added Roles and Id Substraction * Added UserPermission Class * Added Permissions to Media * Deleting all permissions from get queries becouse there is no user content yet. * Added restriction to all Types (which CMS using) * Fixed version conflict of package "System.ValueTuple" * Solved ReSharper errors * Fixed a ReSharper warning * Fixed a ReSharper warning, replaced "TO DO" with "TODO" (this way comments appear in Visual Studio's Task List) * Moved MongoDB primitives (DocRef<>) to HiP-EventStoreLib, updated HiP-EventStoreLib to v0.9.0 * Updated NuGet dependencies, migrated authentication configuration in Startup class to new 2.0 authentication stack (see aspnet/Security#1310) * Updated HiP-EventStoreLib to v0.10.0, updated EventStore.ClientAPI.NetCore to v4.0.2-rc * Bugfix for Swagger UI * Added validation of page IDs when creating/updating exhibits * Added validation of audio ID when creating/updating exhibit pages * Bug fix: Timestamp assignment was missing when emitting certain events * Added to User Score System and Rating System (Exhibit Ratings) User authefication using access token * Added User ID (owner) to all type of content * Added Migration. Where we set admin as owner of old content * Applied all auth rules to API call : POST/PUT/DELETE Store in memory UserId for every content * Changed Implementation of all API Call: GET * Implemented filtering by page type * Fixed auth-related exceptions (GetUserIdentity() now returns a UserIdentity-struct, thus avoiding exceptions and null handling) * Removed debugging code * Syntax fix * Reverted: GetUserIdentity() now returns string again (returning a struct and overriding the ==-operator apparently breaks translation from LINQ to Mongo queries) * Fixed minor merging issues * Update master (#37) (#65) * Implemented page reordering via PUT /Exhibits/{id}, marked old event types as [Obsolete] * ExhibitResult now makes use of the new Pages property * Fixed a validation bug * Removed unnecessary reference addition * Pages no longer create a reference to the containing exhibit * Simplified exhibit usage checks, reworked the areas that expected Exhibit.Referencees to contain page references (new functionality in ExhibitPageIndex is now used instead) * Added stream metadata class (WIP) * Implemented a new migration concept ("stream migration") that allows versioning of streams. Implemented such a "stream migration" that updates the event stream to support the new page ordering feature. * Fixed: *Update-events were clearing the Referencees-list of the corresponding entity (thus e.g., only the pages created/updated after the latest ExhibitUpdate are shown for the exhibit) * Bug fix in migration * Migration fix * Fixed ReSharper issues * Minor documentation improvement * Cleanup of entity classes, more error handling * Added missing [ProducesResponseType(400)] * Hotfix * Hotfix: DocRefList<T> was serialized as array (missing the fields 'Collection' and 'Database') * Fixed a typo which caused the HTTP-route for tag deletion to be malformed (#36) * HIPCMS-761: Moved event sourcing fundamentals to HiP-EventStoreLib (#57) * Removed some types (moved to lib) * Work in progress * Moved more functionality to ESLib * Removed migration notice (moved to ESLib) * Projects now reference NuGet package "HiP-EventStoreLib" from our MyGet-feed * Now using HiP-EventStoreLib v0.3.0 (class InMemoryCache) * Minor changes * Upgraded projects to .NET Core 2.0, updated HiP-EventStoreLib to 0.6.0 * Update HiP-EventStoreLib to v0.7.0 * Updated dockerfile (now uses .NET Core 2.0 image) * Updated NuGet.Config * Updated docker file * Moved NuGet.Config * Updated dockerfile * Moved NuGet.Config again * Moved MongoDB primitives (DocRef<>) to HiP-EventStoreLib, updated HiP-EventStoreLib to v0.9.0 * Updated NuGet dependencies, migrated authentication configuration in Startup class to new 2.0 authentication stack (see aspnet/Security#1310) * Updated HiP-EventStoreLib to v0.10.0, updated EventStore.ClientAPI.NetCore to v4.0.2-rc * Bugfix for Swagger UI * Added validation of page IDs when creating/updating exhibits * Added validation of audio ID when creating/updating exhibit pages * Bug fix: Timestamp assignment was missing when emitting certain events * Fixed minor merging issues * Revert "HIPCMS-761: Moved event sourcing fundamentals to HiP-EventStoreLib (#57)" (#66) This reverts commit 57e8ae7. * Modified project file and Dockerfile (background: I was wondering why commands like "dotnet build" would not automatically pickup the "NuGet.Config" from our repo root folder. Turns out such commands were only looking for a "NuGet.Config" in the project folder because that was explicitly specified in the project file) * Dockerfile changes (this should fix the libssl error; apparently, the Docker image "dotnet:2.0.0-sdk" is based on Debian Stretch instead of Debian Jessie like older versions, so we now use "dotnet:2.0.0-sdk-jessie") * Update master (#37) (#68) * Implemented page reordering via PUT /Exhibits/{id}, marked old event types as [Obsolete] * ExhibitResult now makes use of the new Pages property * Fixed a validation bug * Removed unnecessary reference addition * Pages no longer create a reference to the containing exhibit * Simplified exhibit usage checks, reworked the areas that expected Exhibit.Referencees to contain page references (new functionality in ExhibitPageIndex is now used instead) * Added stream metadata class (WIP) * Implemented a new migration concept ("stream migration") that allows versioning of streams. Implemented such a "stream migration" that updates the event stream to support the new page ordering feature. * Fixed: *Update-events were clearing the Referencees-list of the corresponding entity (thus e.g., only the pages created/updated after the latest ExhibitUpdate are shown for the exhibit) * Bug fix in migration * Migration fix * Fixed ReSharper issues * Minor documentation improvement * Cleanup of entity classes, more error handling * Added missing [ProducesResponseType(400)] * Hotfix * Hotfix: DocRefList<T> was serialized as array (missing the fields 'Collection' and 'Database') * Fixed a typo which caused the HTTP-route for tag deletion to be malformed (#36) * Hotfix (update HiP-EventStoreLib to v0.13.0) (#69) * Updated HiP-EventStoreLib to v0.11.0 * Updated HiP-EventStoreLib to v0.13.0
I have Jwt and Facebook authentication enabled on a Core 2.0 Web API (Jwt is default scheme). When I pass Jwt token in the authorization header, works perfectly. When I pass the access token in the authorization header that I received from facebook, it fails. I've seen several articles from people about the same issue and I've banged my head against this for days on end. I must be missing something fundamental. Any ideas or direction? |
@sschleicher208 I think you have to remove the default and add like this services.AddAuthentication()
.AddJwtBearer("jwt", o => {...})
.AddFacebook("facebook", o => {...}); let me know if it works. |
Thanks for the quick response. This didn't work, but maybe it's my approach. My web api is configured with the appID and secret from facebook. I have a test client that uses the HttpClient to issue rest commands against the API to call the Values controller which has an authorize attribute on it. When testing the Jwt, I generate a token from my API, attach it to the authorization header (bearer), and then call the values action which works just fine. Next I used facebook tools to generate an access token for my app. I then fired up the same console app that I used for the Jwt test but populate the authentication header with the access token but this comes back with a 404 not found. Maybe I cannot just put the access token generated from facebook in the authorization header and expect the API to know that this token is from facebook so use the facebook handler instead of the JWT. Is this even a valid test case? I guess my thought was that if anyone made a request that had this access token in the authentication header, the API would allow it to access actions protected by the authorize attribute. Am I mistaken about it being able to support this? |
How can I do this in .Net Core 2? |
@ThatDeveloper |
@sschleicher208 That's not what the Facebook handler is for. See #1439. |
@Tratcher Yea I eventually figured that out. What I do now is just issue a JWT after a successful external login callback from any external provider. Does that sound right? Seems like that is what is happening behind the scenes when using the azure user store as well. Correct? |
@sschleicher208 Yes, that's what you want to do. |
I'm having some serious issues with MVC AuthorizeFilter in 2.0, a setup I had working in 1.1. I'm using cookie authentication, but without Identity. I've made changes to my Startup.cs file so
}` InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. I then tried adding the scheme to the MVC policy
}` InvalidOperationException: No authentication handler is configured to authenticate for the scheme: se.xxx.authentication |
The authentication scheme is actually CookieAuthenticationDefaults.AuthenticationScheme or "Cookies" in the code you are showing. Setting the cookie name doesn't change the scheme name. There's a different overload of AddCookie which takes the scheme name |
Locking this closed issue. Please direct questions to the discussion thread #1338 or open new issues. |
Note: this issue is closed, you should use #1338
Summary:
The old 1.0 Authentication stack no longer will work, and is obsolete in 2.0. All authentication related functionality must be migrated to the 2.0 stack, any interop between old and new must be side by side apps, as opposed to mixing 1.0 auth code with 2.0 auth code in the same app. Cookie authentication will interop, so 1.0 Cookies and 2.0 Cookies will be valid in both apps if configured properly. The main motivation was to move to a more flexible service based
IAuthenticationService
and away from the old middleware/IAuthenticationManager
design that came over from Microsoft.Owin.IAuthenticationManager
(akahttpContext.Authentication
) is now obsoleteThis was the main entry point into the old auth system. This has now been replaced with a new set of
HttpContext
extensions that live in theMicrosoft.AspNetCore.Authentication
namespace and remain very similar:Configure():
UseXyzAuthentication
has been replaced by ConfigureService(): AddXyz()In Auth 1.0, every auth scheme had its own middleware, and startup looked something like this:
In Auth 2.0, there is now only a single Authentication middleware, and each authentication scheme is registered during
ConfigureServices
, andUseIdentity()
is no longer required (since it was just calling UseCookie 4 times underneath the covers)New
Microsoft.AspNetCore.Authentication.Core/Abstractions
All of the old Authentication namespaces in HttpAbstractions have been deprecated. The new Auth 2.0 stack lives in two new packages inside the HttpAbstractions repo:
Microsoft.AspNetCore.Authentication.Core/Abstractions
.Brief overview:
IAuthenticationService
: used by theHttpContext
extension methods to expose the 5 main operationsAuthenticate/Challenge/Forbid/SignIn/SignOut
IAuthenticationHandler
: Defines the required operations for all handlers: Authenticate/Challenge/ForbidIAuthenticationSignIn/OutHandler
: Implemented to add the SignIn/SignOut methods respectivelyIAuthenticationRequestHandler
: Implemented by handlers that need to participate in request handler, i.e. remote authentication schemes like OAuth/OIDC that need to process 3rd party auth responses.AuthenticationScheme
: represents a logical named authentication scheme to target for any givenIAuthenticationService
method, it binds the scheme name (and optional display name) to anIAuthenticationHandler
which implements the scheme specific logic.IAuthenticationSchemeProvider
: responsible for managing which schemes are supported, and what the defaults are for each operation (the default implementation just reads from theAuthenticationOptions
)IAuthenticationHandlerProvider
: responsible for returning the correct handler instance for a given scheme and request.IAuthenticationFeature
: used to capture the original request path/pathbase so redirects can be computed property after anapp.Map()
Types that are mostly unchanged, just with new homes:
AuthenticationProperties
: metadata for authentication operations.AuthenticationTicket
: used to store a claims principal (user) + authentication propertiesAuthenticateResult
: return value forAuthenticateAsync
, contains either a ticket, or a failureSecurity repo:
Microsoft.AspNetCore.Authentication
/ AuthenticationHandler changesAll of the core abstractions and services for authentication live in HttpAbstracions, but there's an additional layer of base classes/functionality targeted towards implementation of AuthenticationHandlers. This is also where the AuthenticationMiddleware lives. The handlers themselves for the various implementations aren't drastically different, but there were a fair amount of changes
Microsoft.AspNetCore.Authentication
Overview:
AuthenticationMiddleware
:UseAuthentication()
adds this middleware which does two things. By default It will automatically Authenticate usingAuthenticationOptions.DefaultAuthenticateScheme
to sethttpContext.User
if specified. It also will giveIAuthenticationRequestHandler's
a chance to handle the request.AuthenticationSchemeOptions
: Base class for options used with theAuthenticationHandler
base class, it defines two common properties in Events and ClaimsIssuer, as well as a virtualValidate()
method that will be called on every request by the handler.AuthenticationHandler<TOptions>
: Abstract base class for handlers who must implementHandleAuthenticateAsync
. The rest ofIAuthenticationHandler
is implemented with some reasonable defaults, Challenge(401)/Forbid(403), and logic to handle per request initialization usingIOptionsMonitor<TOptions>.Get(authenticationScheme.Name)
to resolve the handler's options.RemoteAuthenticationHandler<TOptions>
: Adds the abstractHandleRemoteAuthenticateAsync
and implementsHandleAuthenticateAsync
to call this method. This is meant to be used for 3rd party authentication, i.e. OAuth/OIDC. It adds an additional constraint to TOptions that requires them to beRemoteAuthenticationOptions
which adds a bunch of settings like CallbackPath, CorrelationCookie, Backchannel which are needed to talk to a remote authentication provider.AuthenticationBuilder
: is a new class which is used to group all of the AddXyz() authentication methods. This is returned byservices.AddAuthentication()
and is where specific authentication methods are expected to add themselves as extension methods, i.e. AddCookie(), AddGoogle(), AddFacebook().Event changes overview
At a high level, there 3 main kinds of events:
BaseContext
events which are the simplest and just expose properties with no real control flow.ResultContext
events which revolve around producingAuthenticateResult
s which expose:Success()
: used to indicate that authentication was successful and to use the Principal/Properties in the event to construct the result.NoResult()
: used to indicate no authentication result is to be returned.Fail()
: used to return a failure.HandleRequestContext
events are used in the IAuthenticationRequestHandler/HandleRemoteAuthenticate methods and adds two more methods:HandleResponse()
: used to indicate that the response was generated and the AuthenticationMiddleware should not invoke the rest of the middlewares in the pipeline after it.SkipHandler()
used to indicate that this handler is done with the request, but subsequent handlers will be called, as well as any other middleware in the pipeline if none of those handlers handle the request.AutomaticAuthentication/Challenge
have been replaced byDefault[Authenticate/Challenge]Scheme
AutomaticAuthentication/Challenge
were intended to only be set on one authentication scheme, but there was no good way to enforce this in 1.0. These have been removed as flags on the individual AuthenticationOptions, and have been moved into the base AuthenticationOptions which can be configured in the call toAddAuthentication(authenticationOptions => authenticationOptions.DefaultScheme = "Cookies")
.There are now overloads that use the default schemes for each method in
IAuthenticationService
DefaultScheme
: if specified, all the other defaults will fallback to this valueDefaultAuthenticateScheme
: if specified,AuthenticateAsync()
will use this scheme, and also theAuthenticationMiddleware
added byUseAuthentication()
will use this scheme to setcontext.User
automatically. (Corresponds to AutomaticAuthentication)DefaultChallengeScheme
if specified,ChallengeAsync()
will use this scheme,[Authorize]
with policies that don't specify schemes will also use thisDefaultSignInScheme
is used bySignInAsync()
and also by all of the remote auth schemes like Google/Facebook/OIDC/OAuth, typically this would be set to a cookie.DefaultSignOutScheme
is used bySignOutAsync()
falls back toDefaultSignInScheme
DefaultForbidScheme
is used byForbidAsync()
, falls back toDefaultChallengeScheme
"Windows" Authentication(HttpSys/IISIntegration)
The host behavior hasn't changed too much, but now they each register a single "Windows" authentication scheme. Also IISIntegration now conditionally registers the handler only if windows auth is enabled in IIS (if you have the latest version of ANCM, otherwise it's always registered as before).
Authorization changes
IAuthorizationService.AuthorizeAsync
now returnsAuthorizationResult
instead of boolIn order to enable scenarios around authorization failures,
IAuthorizationService
now returns a result object which allows access to the reasons whyAuthorizeAsync
failed (eithercontext.Fail()
, or a list of failed requirements)Removal of
ChallengeBehavior
=> newPolicyEvaluator
In Auth 1.0, there was a
ChallengeBehavior
enum that was used to specify either Automatic/Unauthorized/Forbid behaviors to signal to the auth middleware what behavior the caller wanted. Automatic was the default and would go down the Forbid(403) code path if the middleware already had an authentication ticket, otherwise would result in Unauthorized(401).In Auth 2.0, this behavior has been moved into a new Authorization.Policy package, which introduces the
IPolicyEvaluator
which uses bothIAuthenticationService
(when requested via policy.AuthenticationSchemes), andIAuthorizationService
to decide whether to return a tri statePolicyAuthorizationResult
(Succeeded/Challenged/Forbidden).Overview of
[Authorize]
The
[Authorize]
attribute hasn't changed much, but the there were some implementation details that have changed significantly in MVC'sAuthorizeFilter
, and here's an overview of how things work:AuthorizeFilter source
[Authorize]
attributes on the controller/method/globally.IPolicyEvaluator.AuthenticateAsync(policy, httpContext)
is called, by default, if the has specified anypolicy.AuthenticationSchemes
,AuthenticateAsync
will be called on each scheme, and each resultingClaimsPrincipal
will be merged together into a single ClaimsPrincipal set on context.User. If no schemes were specified, the evaluator will attempt to use context.User if it contains an authenticated user. This is usually the normal code path, asDefaultScheme/DefaultAuthenticateScheme
will be set to the main application cookie, and theAuthenticationMiddleware
will have already set context.User using this scheme'sAuthenticateAsync()
Authenticate logic
AllowAnoynmous
was specified, authorization is skipped, and the filter logic short circuits and is done.IPolicyEvaluator.AuthenticateAsync(policy, authenticationResult, httpContext)
is called with the result from step 2. This just basically turns into a call toIAuthorizationService.AuthorizeAsync
, and the result is used to determine the appropriateChallenge/ForbidResult
if needed.Claims Transformation
Simpler, new
IClaimsTransformation
service with a single method:Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
We call this on any successful
AuthenticateAsync
call.Known issues/breaking changes:
The text was updated successfully, but these errors were encountered: