I'm looking at the AspNetIdentity_2fa sample and trying to modify it to include some dynamic claims for users. Let's name it calculated_value claim which is created dynamically when a user is authenticated, and then is included in the user's claims list and passed with the the authentication token. I know I could create a separate Web API to get this value but since it is small data and that it is needed as soon as a user is authenticated, I thought I'd just pass it as claim. In the samples I see that claims always coming from static or hard-coded data. How can I create dynamic/late-bound claims?
Thanks!
Some time ago I spent some time on trying to integrate Identity Server v3 with Active Directory. I wanted to authenticate users via AD and to read "claims" from AD. To do so I provided a custom implementation of IUserService. It was more or less based on in memory implementation of these interface i.e. InMemoryUserService.
When your custom implementation is ready you have to register it. However, AspNetIdentity_2fa sample project already registers a custom implementation of IUserService i.e. UserService (just search a project for this class). It is derived from AspNetIdentityUserService which implements IUserService.
So, instead of providing completely new implementation try to modify it. I think that you should look at AuthenticateLocalAsync, AuthenticateExternalAsync and GetProfileDataAsync methods (see InMemoryUserService for reference) and override them. First 2 are used to authenticate users and the last one to read requested claims for users.
Related
I'm designing the architecture for a college project and I don't know how to deal with the user authentication and authorization part of it. The project is a desktop Electron app which would need two types (hence the roles) of users. They both need to be authenticated in order to use the app, and depending on their identity, they will have different authorizations. Since the project is meant to be used by teachers and students as part of a laboratory class after it is done, I don't think more than 30 people will be using it at the same time.
My first thought was using a PostrgeSQL database in AWS for this and implementing the authentication myself, but this means that users will have to sign up and create a new profile, which means remembering yet another <username/email, password>. Trying to avoid this, I read a bit about OAuth 2.0 and OIDC, and how it can be used to authenticate and authorize users without implementing either of those tasks oneself, but rather delegating the task to OIDC. I created a free account with Auth0 and thought about using it for the OIDC integration but after reading about 40 pages of an "OIDC integration handbook" they offer for free, I could not know if I would be able to distinguish my user base through these roles or tags as I mentioned. I just followed the steps in the tutorial handbook and tried to understand how the auth flow worked, but that didn't give me any information on my question.
So all in all what I want to know is: is it possible to implement this with Auth0 (free account) without having to use a third-party database solution (such as PostgreSQL with AWS)? If not, what would you recommend me to look into? Preferrably a solution that will let me discriminate between the two types of users BUT at the same time taking advantage of the OIDC implementation of Google for example.
There are 2 separate solutions here:
DESKTOP AUTHENTICATION
The 2 standard requirements are:
Use Authorization Code Flow (PKCE)
Login via System Browser
You listen for a login response via one of these mechanisms (I prefer the latter):
Loopback web server
Private URI scheme OS notification
My blog has some tutorials + code samples that use Electron. You can run both of the above listening options and see what you prefer.
API AUTHORIZATION WITH ROLES
You need to make roles available to the API via claims. This can be done by either of these mechanisms (I prefer the latter):
Including roles in access tokens via Auth0
Get the API to read user roles from its own database
My Authorization blog post discusses building up a claims object in an easy to extend way. The main objective is usually for API OAuth processing to result in an object something like this:
class UserPrincipal {
// The technical user id from the access token
string sub;
// The user id from your own database
string userId;
// The user's roles
string[] roles;
}
Given that object you can do things like this:
Use role based authorization when needed
Serve up user resources after login from your application data
TO SUMMARISE
Auth0 will meet some of your requirements and may be all you need in the early days. You will probably need to manage non OAuth user data in your API at some point though.
Happy to answer any follow up questions ..
Here is my development environment:
Intranet Website
Active Directory Authentication/Authorization
Asp Net Core
I am trying to get the data stored in Active Directory attributes when a user enters firstly to any page in our application. All users rights and permissions, employeeid, studentid, etc.... are stored in AD Attributes and Security Groups. Some Attributes need to be displayed on the website too.
Let's say my website got the following urls...
http://mysite/Home/Index
http://mysite/Student/Index
http://mysite/Student/MyJobs
http://mysite/Staff/Applications
etc....
Any users can go onto some areas/urls of the website freely from other Intranet portals and I don't know where should I write the code to fulfill that criteria. The problem is that, there is no specific entry point to the application like http://mysite/Login or Authenticate, etc. If there is, I could load all users details and rights from AD on that single entry point.
In MVC5 era, I used Custom Global Authorize Attribute and put it on the BaseController is inherited from all other controllers to load that AD data. I put the AD's data into Session on the first hit and use the Static Class to display on Views and use in Controllers. But when I did some research in MVC Core, some say that it's outdated and I should use the Authorize Policy instead of custom Authorize Attributes.
Getting the data from Active Directory is already achieved by using my old webservices and we don't need to worry about .Net core not supporting AD yet.
I looked at the tutorials about Policy and saw something about Claims and Custom User Managers. I couldn't decide which one I should use to load data from Active Directory to the object (probably Scoped Object DI) which lasts for the whole user's session.
Should I load the data onto claims attributes
Eg...
var claims = new List<Claim>();
claims.Add(new Claim("UserName", "John.Smith", ClaimValueTypes.String, Issuer));
claims.Add(new Claim("RefNo", "02343001", ClaimValueTypes.String, Issuer));
claims.Add(new Claim("Email", "MyEmail#email.com", ClaimValueTypes.String, Issuer));
Or Should I write customized SignInManager and IdentityUser?
Eg...
public class ApplicationUser : IdentityUser
{
public string RefNo { get; set; }
public string Email { get; set; }
}
Is there anywhere I could put my code to check AD and load data?
And should I store the data in that Claimed Object rather than using Session Data?
Could you guys please advise me? Feel free to criticize if I miss anything and my idea is not working.
You're right in saying there's no System.DirectoryServices yet (it's on the backlog, I promise) so there are a couple of places to do this.
If you're already using Integrated Authentication you have SIDs for group membership, which are resolved when you call IsInRole(), so you can use role based membership (rather than Claims based) to solve basic authentication problems.
However if you want to support a forms based mechanism then you should look at using the cookie middleware, raw, to at least give you a simple login, calling your web service to validate your login. You could query your API in the controller code, and write an identity cookie. This cookie automatically encrypted and signed, so it can't be tampered with.
The problem comes when you want roles, and attributes. If you head down the cookie route you might be tempted to put all of those as claims in the identity before writing the identity out as a cookie. This might work, provided there are not too many - cookies have a maximum size (browser dependent, but under 4k usually). You can used chunked cookies, but there's a performance impact here. Instead you might use a reference cookie, where you put in a reference to another store where the actual fully populated identity is stored, be it session, redis or something else.
Then in the claims transformation middleware you can pull the reference out, go to your store, and rehydrate the identity.
I'd honestly avoid trying to merge all of this into ASP.NET Identity. That's mean to be the sole source for user information in an application, and in your case that's not true. Your sole source should be AD.
There's also a port of Novell's ldap library to core, which should stand in nicely for DirectoryServices should you want to avoid your web services approach.
I've been knocking my head up against this problem for a few days now and after seeing dozens of examples all over the web I'm no closer to a solution.
I need to to various types of login, eventually. For right now I'd settle for one. I would like to login using fields other than username and password. Let's say I want to use name, last name and birthdate.
I thought the easiest way to go was to just implement my own UserDetailsService and plug it into my provider. But UserDetailsService only has one method, loadByUsername, which doesn't seem to be the most intuitive way to load my user.
So then I thought it would be better to implement my own AuthenticationProvider ... or simply extend DaoAuthenticationProvider, and override the authenticate() method. But that method takes an Authentication as a parameter ... can I used a POJO, with only name, last name and birthdate fields, as an Authentication object?
Ditto for Authentication Manager. In fact, in the api for AbstractUserDetailsAuthenticationProvider (where the authenticate() method lives) it says that it "Performs authentication with the same contract as AuthenticationManager.authenticate(Authentication)"
But people seem to implement Providers more than Managers. oddly enough, most examples of "custom" Providers and UserDetailsServices ... all implement authentication with username and password, which is was Spring Security does by default anyway!
Can anyone shed some light on this subject? As I said, there are tons of examples but they are all very similar and none that I can find use an Authentication Object that isn't username/password.
Bonus points if someone could also tell me the best way to go about having more than one Provider/Manager -- for example, one like the one described above, and another that authenticates using name and social security number, for example -- and to use one or the other (not both, and not the second one if the first one fails!) depending on a parameter pass from the url, for example.
I'm not sure if you had already solved this challenge. But, it seems that I have a similar case with you. My login page requires additional field 'organisation' aside from 'username' and 'password'. Here is what I did:
I've used custom AuthenticationManager and custom UsernameAndPasswordAuthenticationFilter.
The custom filter is for retrieving the additional field from HttpServletRequest. I added the field to the session and retrieved it inside custom AuthenticationManager.
Performed authentication with the three fields using another bean/service.
I am still pretty new to ASP.NET Web API. I am currently working on the authentication part of a new application based on Web API, which is developed using some libraries/kinda framework of the company.
There is already some MVC application - they are using forms based authentication and they are not using the IPrincipal to store information about the user, rather a unity based approach, keeping data in a custom IUser object (basically kept on the session).
The Web API application is going to be stateless (no session), just that I am going to add some user related information in the authentication cookie (retrieved per request in the Application_PostAuthenticateRequest).
I am a bit undecided to keep this user related data in a custom implementation of IPrincipal (as I noticed to be a practice) or use the current approach of other applications in the company utilizing an IUser - served by Unity, using a per request lifetime manager.
Which do you consider to be the better approach?
If you're keeping track of Users per session, try using Singleton classes, if you're about to make a log of the users that entered the session, write it down in a textfile like a whitelist.
Our system uses a custom roles, and authentication system to Authenticate users.
I am now looking into the service side validation/security.
I want implement our custom Authentication, Authorization on the wcf too.
I have done some investigation, it looks like I could use the PrinciplePermission attribute on the contracts to allow/deny access. The default just calls the IsInRole method on the IPrinciple and the IsAuthenticated on the IIdentity.
So I have 2 questions:
How do implement my own custom principle which has additional data/methods?
How do I add addition checks to the PrinciplePermissions? e.g (IsExternal which will check if they are accessing the service from the intranet or internet [have a mechanism to monitor this already])
Thanks
After some experimenting I came up with a custom written solution:
I based my solution in Kyle McClellan's Authorisation Sample. I adapted the attributes to look at a custom class to retrieve the user.
To get around the async problem I loaded the user and his relevant data in the App.xaml prior to instantiating the MainPage, I then make use of a global singleton, which I called SecurityContext, to access user data.
The SecurityContext is an in-memory store of the user data that can be accessed clientside.