I'm looking over the auth docs
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization
Basically what I would LOOOVE to do is simplify our service auth. Basically say "If this is being run in the context of an authenticated CMS user (in the API) use that person, if user is ANON, check for a JWT in the header, and run in the context of that user"
So I assume this would all be some sort of custom attribute? (I mean ideally I'd like an attribute or something). Right now we just have a method that lives at the top of every call to do this validation... would love to abstract it all out if possible somehow.
Anyone have any suggestions?
Steve
It's not included in the framework itself however there are a couple of external projects that enable token-based authentication with ServiceStack:
StatelessAuthentication
Using IdentityServer 4 with ServiceStack and Angular
Auth0 ServiceStack Integration
ServiceStack JWT Token validation for Auth0
Related
In one of my project need to consume JWT token from asp.net core web application. My trial project is on github https://github.com/SapanPatibandha/JWTAuthentication
This has one server JWTAuthentication which is generating jwt token base on username and password.
Second component is AnyAPI which method is protected by self verification of JWT.
Third important part and where I have problem is Web application.
Need to create login screen in this application, base on this user detail call login api from JWTAuthentication and use that token for all further use of api from that web application.
I am not sure about middleware configuration and how to store this token on web application.
Thanks
IMO, What you asking for is a journey that need some investigating time, that's not what could be answered shortly, so... I'm gonna make this as compact as possible
What you're doing in the repo is hand-generate and validate Jwt Token. If that's required, investigate these stuff:
Generating Jwt on central identity provider server (which you currently have)
Validate Jwt on api resource (which you currently comment that out)
On application(seems like you make use of classic MVC or razor page), create login form that use ajax to get Jwt from identity provider server, store it on client side (browser), then attach it with every request that make use of AnyAPI, by cookie or header or something you saw reasonable. Or if you choose to save the token on Server side, implement your own session-Jwt mapping logic(Actually, some kind of Js SPA would be more suitable for this kind of approach).
Another approach would be implement a more proper Oauth implementation. I consider 2 most widely acknowledged in .net ecosystem would be Identity Server and OpenIdDict. Highly recommend to check them out.
I'm working through building a prototype of an IdentityServer4-based process where I have an Angular SPA, a "Back-end for Front-end" (BFF) ASP.NET Core API, and a back-end API service (also ASP.NET Core) all interacting with a derivative of the https://demo.identityserver.io/ IdP.
My BFF and back-end API services are based on the samples found at "https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore3/BFF"
Everything is going pretty well until I try to create the scenario where the user chooses to logout from the IdP Logout page. The BFF service does not 'notice' the user's token and session has been revoked/removed until the tokens expire much later.
I suspect I should be using the process found in the sample https://github.com/IdentityServer/IdentityServer4/tree/main/samples/Clients/src/MvcHybridBackChannel where a cookie event handler in the BFF service implements ValidatePrincipal(CookieValidatePrincipalContext context) to make an explicit call to the IdP to verify the user's token on each request.
First question: is this the correct pattern to accomplish this? Or am I making this needlessly complex?
Second question: what is the method to ask the IdP "Is this session still valid?" (This seems like something that should be easy to do!)
Thank you in advance.
First question: is this the correct pattern to accomplish this? Or am I making this needlessly complex?
Yes it it correct, when you logout directly from IDP you need to inform the client apps that user has signed out. If you are using cookie on the BFF you need to do the same for it. Read more here
Second question: what is the method to ask the IdP "Is this session still valid?" (This seems like something that should be easy to do!)
Idp is not validating the session or cookie, it validates the token. session/cookie management is the responsibility of client apps. Read more here
If i host my Identityserver4 and the Api in the same Asp.net Application.
What will be used for authentication for the API Controllers?
The Cookie from Identityserver or the token which i get from the oidc-client in my SPA application?
I my tests i can access the API, also if i didn't send the token within the angular http reqeuest as long as i have the Cookie...
But is this a correct and save way???
The MVC Controllers for Identityserver are protected with ValidateAntiforgeryKey, but not the API Controllers.
Does it make sense to host both in the same Application???
Edit:
In Details, the API is used for managing the IdentityServer.
CRUD Operations for Clients, Users, Resources,...
For example:
The IdentityServer is reachable at http://localhost:5000
I want build an Angular2 SPA Admin UI which is available at http://localhost:5000/admin
The reason for mentioning ValidateAntiforgeryKey is, because if i only use Cookie Authentication for the CRUD API i should also protect these API'S with ValidateAntiforgerKey, or?
It sounds like your API and Identity Server are two separate concerns and should be handled as two separate apps. This makes it a lot easier to maintain.
You need to set up an ApiResource and a Client where you add the ApiResource as an AllowedScope in your Identity Server configuration.
Then in your API app, you must add add the authentication middleware UseIdentityServerAuthentication.
The details are explained here:
http://docs.identityserver.io/en/latest/topics/apis.html
I can see you are mentioning ValidateAntiforgeryKey. This attribute is not used for protecting against unauthorized users, but to make sure form data is being posted from legitimate forms.
After dooing some research i understood there are many ways to implement authentication and authorization in WebAPI 2 ...
I'm looking specifically at Token based authentication
implementing a custom OAuth Provider and injecting it to OWING pipline
implementing an "Authentication" controller which will generate the required token sotre it to the DB and use a custom authorization attribute (can understand the advantage or disadvantage of this way from #1) see here http://www.asp.net/web-api/overview/security/authentication-filters
A full custom authentication framework implementing token authentication like described here http://www.codeproject.com/Articles/630986/Cross-Platform-Authentication-With-ASP-NET-Web-API
What is the best way to go here ?
I am very confused ...
You can use the Microsoft Wilson library which will do the token authentication and validation for you. The latest release of the Wilson library can be found here https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet
It uses the industry protocol OpenId Connect and thus provides a secure way for token authentication in OWIN middleware. It would save you the effort of doing it yourself.
I am struggling with understanding how to implement the following in Web API 2's OWIN pipeline.
I am building an application that will allow users to log in with several third-party identity providers such as Facebook, Twitter, LinkedIn, etc. However, I want the authentication step to be performed entirely client-side. For example, Facebook provides developers a snippet of markup and JavaScript that perform the authentication within the browser, resulting in a Facebook access token--all without any calls to my API.
The Web API templates that ship with Visual Studio 2013 all seem to assume that the API itself is in charge of the authentication flow. I have successfully gotten this style of authentication working, but in my opinion it is not the responsibility of the API to perform this work.
Here is the approach I have been trying to implement (so far unsuccessfully):
Provide endpoints like /authenticate/facebook that accept the appropriate access token and return a JWT with "decoded" claims if the access token is valid. This JWT would have similar claims regardless of the third-party identity provider. For Facebook, I think this involves a call to Graph API's /me endpoint.
Store the JWT in the browser's localStorage for subsequent API calls
Send the JWT in the Authorize header for each API call
Avoid cookies if at all possible
My questions:
Is this an appropriate way to handle third-party authorization?
Should the JWT's expiration match the third-party access token's? I assume yes, but I want to be aware of any caveats here.
Where and how do I store the third-party access tokens for use on subsequent API calls? Do I include them with the JWT?
Is there a template I can use out-of-the-box, or perhaps an online resource that implements authentication and authorization in this way? I don't understand how to use Web API's many classes and features to implement this.
I have this mostly figured out now. I believe my architecture choice is the correct one after much research, specifically into the so-called "assertion flow." I am using Thinktecture's Identity Server 3 project to act as my STS. I am using a custom implementation of ICustomGrantValidator to perform the validation of the Facebook access token and conversion to claims.