How to persist users who login to my application using Spring Security 5 OAuth SSO Client - spring-security-oauth2

I know the OAuth support now native to Spring Security 5 is fairly new. I've gone through all the documentation, samples and blogs that i can find about its capabilities. However, I cannot find anything about how to do what I want to do.
I have an application that I want to allow users to sign up for and allow them to authenticate with whatever third party service they choose to use (e.g. Github, Facebook, Google, etc.). I want to be able to know if they are a newly registered user so that I can ask them more information about themselves; Just like you do here when creating a new account on Stackoverflow but using Google for your authentication provider. Or if they are an existing user so that i can re-associate this information to them; just like every other website does. I also want to be able to assign additional authorities to some users to give some additional capabilities in my application.
All of this says to me is that there must be a way for me to hook into the login process to both persist a new user and to fetch information about a pre-existing user. However, all of the examples around creating the principle and assigning authorities deal with determining them from the information retrieved from the external providers information, and not from my systems own persisted information.
I'm pretty sure if i can figure out how to persist a newly met user, then I believe I can look up existing users with a custom OAuth2UserService, and adding new authorities to them and then associating those authorities should be pretty simple with my own GrantedAuthoritiesExtractor. All of this assumes my understanding is correct.
Any help is greatly appreciated

Related

ASP.NET Identity - Maintaining information about anonymous users

I'm just looking into ASP.NET Identity, which seems that it is the most preferable solution for user authentication in ASP.NET apps these days (replacing all the ASP.NET Membership stuff from the past).
I am looking for a solution that would allow to maintain information about anonymous users. Even if the user is not authenticated, we can collect and store most of the profile data that we could store if the user was authenticated.
Even if the user is anonymous, it makes sense to store data like:
shopping cart
comments he's written on the site (so that he can edit them as their creator)
various site preferences (his preferred language, and many other settings)
Then when the user registers, we can offer to copy some of this data into his new user profile (or copy it automatically) depending on what data it is.
Is it possible to achieve this scenario with ASP.NET Identity? It seems that when a user is anonymous in ASP.NET Identity, he cannot have any user profile data.
In order to use the same tables to store all this information as for authenticated users, we might need to create a new user in the system for every new visitor that comes to the site and does some action that requires storing of some user data.
After that, we'd need to pass some cookie identifier to the user, so that we can always connect the data to the user, which can be seen as some form of authentication (although invisible to the actual user). That way, the guest user could actually represent an authenticated user of the system (maybe he'd just have a special role?), even though to his knowledge he's anonymous.
What do you think about this approach? Are there any ways where ASP.NET Identity can help with this?
I found these two related Stack Overflow questions, but I haven't found my answer in them:
Does ASP.NET Identity 2 support anonymous users?
ASP.NET Identity - Anonymous profiles
Edit:
I discovered that there's a mechanism called Anonymous Identification in ASP.NET that seems to solve part of the issue.
https://msdn.microsoft.com/en-us/library/91ka2e6a(v=vs.85).aspx
Maybe it can be somehow integrated with ASP.NET Identity?
Edit2: As noted in the comments, the documentation for Anonymous Identification seems to be outdated and it's quite probable that Microsoft will not be focusing on this much in the future. Solutions that work with ASP.NET Identity or other OWIN-based solutions are preferred.
Asp.Net Identity has no such thing, and it will not be secure identify the anonymous user even through hip IP or a Cookie in his browser, you can ask the user to register with very minimum info or through FB or Twitter to make the registration process as short as possible, and later he can complete his profile, this way you will make sure the data is linked to an actual profile.
ASP.NET profile properties allow your application to track and permanently store user-specific information. For example, users can specify a postal code or a favorite color scheme, and your application can store that information and retrieve it from anywhere in the application. ASP.NET automatically matches the current user — whether the user is anonymous or logged on — with the personal information that is stored for their user account.
Configuring Profile Properties
You will begin by configuring your application to enable profile properties. You will then define the first property that you want to track for each user. This property is named PostalCode and will be tracked for both anonymous and logged-on users.
Source: https://msdn.microsoft.com/en-us/library/taab950e.aspx

ASP.NET Identity - How to manage claims?

I would like to implement claims based authorization in a Web Api project. I understand the idea of claims and can manually add a claim to a user and authorize a request based on it. However, I don't know how I should manage the claims, assign them to users and update them in future.
For example, say I have a Product entity and ProductCreate, ProductRead, ProductUpdate and ProductDelete claims for the CRUD operations on this entity. So I have a few questions:
I can store the claims in the DB, but what is the best way to add the "default" claims to a user on registration?
If I add new functionality to list the products which is only authorized if the user has the ProductList claim - new users would get this claim, but how would I add this claim to all existing users in the system?
Should there be a limit on the number of claims associated with a user? In a larger system with many entities, a user could end up with hundreds of claims
As I said, I know how to physically add the claims to the user etc., but it's more the bigger picture of the process of how you would manage claims and users in a real world example.
Thanks!
UPDATE
Thanks Brendan, I appreciate your help! I don't know if I'm misunderstanding something fundamental or if the answer is staring me in the face - either way, I'm not getting it.
So I have web api and would like to give granular access to the different controller methods. As the Admin, I want to be authorized on all calls so I should have all claims. Registered users should have read access to some methods and you as a moderator should have update and create access to some. My understanding is that these claims should be stored in a DB (SQL server in my case) somewhere and "assigned" to the user when they register. Using Asp.Net Identity, each user's claims would be stored in the AspNetUserClaims table, so when they login they get all their claims in the token by default. Simples!
What I am missing is the process of how you would handle the claims that should be assigned to a user when they register, what claims should a Moderator get etc. and how would you add / remove privileges. It doesn't seem right to me to have this in the code as adding a new claim in the system would require a rebuild and new deployment.
Also, if I add new functionality which requires new claims for different types of user, how would I make sure that the next time an existing user logs in they get the new claims as well as the ones they were assigned when the first registered.
I hope I am making sense, I may be mixing up some of the Role-based thinking with some of the Claims-based thinking which could be the source of my confusion. I just haven't seen any examples of how you would manage an application with many, many claims in the real world.
Thanks again!
That's exactly the same question and issue i'm running into. All I found is info on how to create a claim using the manager classes but nothing on where to manage these claims.
There can be different combination of access to give to a user and if my UI is a disconnected UI from my API, I don't think i would want the ui to manage these claims for me.
Other than mucking and creating a claims manager class with a claims table did you figure anything built in that can be used?

What's the practical workflow using claims for authentication and authorization in a web application?

I just don't still get Claim Based Authentication/Authorization workflow.
The application allows authentication via Facebook.com
After the user is authenticated, an admin can give her/him a claim of having the role of Manager, which creates another claim (where?)
Of course, this claim won't be on the facebook.com server, question 1: where should that claim be stored?
When the user log in again later, I get the claim of facebook.com and I should get the claim from the application. and merge them?
How is the workflow? Trying to understand claims in practical usage.
Basically, Facebook tells me that I'm john#doe.com, and 'field in the blanks' adds a claim that I'm also a manager of domain.com
then I pass those claims to domain.com?
How should I configure in asp.net the application at domain.com to trust Facebook and 'filled in the blank piece' and request claims from both?
I guess I'm using external providers for Authentication and my own provider for Authorization, how this is created on ASP.NET (web API / MVC)?
UPDATE (for clarification)
Let's get backwards. I create a web application where users can register.
'Somehow' there's an trusted ClaimsBased authority somewhere (this should be another application??) where I request the claims for a particular user to see if have particular rights on my application.
So I imagine something like :
/authserver/claims
and my validation checks if X claim is met to do certain operations.
later I add to Facebook. now I have
/facebook/claims
which tells me the user is X
and
/authserver/claims to see if can do operation X on resource Y.
how this is managed on ASP.NET? and where my own claims should be created/exposed/developed.
I think I'm missing something fundamental here.
I think the important thing to understand is the difference between authentication and authorization.
Authentication - the act of confirming the truth of an attribute of a datum or entity.
Authorization - the function of specifying access rights to resources, which is related to information security and computer security in general and to access control in particular.
So, typically for secured system, the workflow starts with Authentication. When a user first connects/uses a system, then are not authenticated (lets say this user is of a type/group Anonymous). The act of the system determining the user is not authenticated is an Authentication in and of it self. Based on being Anonymous, then the act of the system determining what that type of user anonymous has access too is now authorizing what the user can do. For very secure system, the only access anonymous has is to the login screen/page. Once logged in the user is assigned a unique identity and assigned some type of group policy/role (if not already created).
with a web-based application and having a website (#1) authenticate for another website(#2) it becomes a bit more complicated. When I log into StackOverflow(#1), I use my Gmail(#2) account. I get redirected to Google with some special way for Google to know that the page I came from/to go back to. This could be a special key/url combination or for less restrictive access, usually has to do with return url (after I say, yes, where I go back too). Google will create a special authentication token that is specific to the url I am returning to. It is tied to the URL because that means that my token on StackOverflow won't allow me or anyone else to log into say NewEgg for example (in other words someone at StackOverflow with access to the database can't use my token to authenticate as me on some other website, but technically they could log in as me on StackOverflow, but they own the website, so that doesn't really matter). Now I am authenticated on StackOverflow (but technically StackOverflow doesn't even need to know any information about me, just my Token).
On StackOverflow as a new user, a new account is created. This account probably has a one to many relationship to my unique account on Stack Overflow and multiple of logins (and type of logins, OAuth, OpenID or SO Login). Once the account is created, I have whatever access they have setup by default. If I need more or some trigger (lets say based on my Reputation points :) I now have access to Administrative functionality (given some role). That role is tied to my account and indirectly tied to my authentication. This means that I can create additional logins (say a Local SO Login) but keep my Account.
As for each Authentication resource (Google, Facebook, etc) there will be difference schemes for Authentication, but there will always be at least a token (or more than one token) for a website to say who I am (in a generic way).
So website #1 (Stack Overflow) has requested website #2 (Google) to Authenticate me. But only website #1 knows what am I Authorized for.
For role specific functionality, there are a good number of answer on SO dealing with ASP.Net Identity and the Role Manager:
Creating Roles in Asp.net Identity MVC 5
mvc 5 check user role
A much more Indepth look into Identity with MVC - Extending Identity Accounts and Implementing Role-Based Authentication in ASP.NET MVC 5
If you're using ASPNET.Identity (http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity), you can add a Role claim type to the user. It'll be associated with the userlogin, so when the user authenticates with Facebook, these user claims will be added and available in MVC.
See the following code fragment:
var acRes = await UserManager.AddClaimAsync(userId, new Claim(ClaimTypes.Role, "MyRole"));

Benefits of symfony2 security over storing in session variable on own?

How does Symfony's security component work?
Currently, I grab user login data, auth them against a database, and store their info in a session variable to log them in. When a user accesses a page, it checks their session to ensure they have rights to view a specific page. All of this is organized into services.
I've been looking into Symfony's security component but can't figure out exactly how it works. Specifically, is there some extra security benefit (I have an admin panel that I need to have proper security on) that it offers?
I also hate learning framework specific stuff without understanding what's going on, so would appreciate a general breakdown of how the component works.
Thanks
This video is a good resource of how the security component works. The video is from the Symfony live conference in Paris last year. The speaker Johannes Schmitt is the one who has led the development of the security component.
http://www.youtube.com/watch?v=lSxgEK8WKGA
Security is a two-step process whose goal is to prevent a user from accessing a resource that he/she should not have access to.
In the first step of the process, the security system identifies who the user is by requiring the user to submit some sort of identification. This is called authentication, and it means that the system is trying to find out who you are.
Once the system knows who you are, the next step is to determine if you should have access to a given resource. This part of the process is called authorization, and it means that the system is checking to see if you have privileges to perform a certain action.
More information can be found at :
http://symfony.com/doc/current/book/security.html

secure way to authenticate administrator in ASP.NET site using OpenID with DotNetOpenID

Encouraged by SO, I'm trying to write an ASP.NET site that uses OpenID for user authentication. It's a regular WinForms site (not MVC.NET), using the DotNetOpenId library for authentication.
Is it safe for me to permit/deny administrative functions on the site by simply comparing the current session's "ClaimedID" (as returned in the OpenIdLogin_LoggedIn event, as member DotNetOpenId.RelyingParty,OpenIdEventArgs.Response.ClaimedIdentifier) to a known administrator's OpenID (i.e. mine)?
If so, is it safe for this ID to be visible (e.g. in open source code), or should it be "hidden" in a configuration file or a database row? (I know it's better design to make it configurable, my question is just about safety.)
My solution is to follow the same idea of the Roles table. After you've authenticated the user, look up that user's roles. If the user has role "Administrator" in the UserRoles table, then they can do whatever the Administrator can do.
I don't broadcast open ID's in my app. They're stored in the table. On every action result, I'm hitting the Users table, since I have also modified mine to store various user state information. With the exception of the home page, there is going to be some user information that I need from that table. I'm using LINQ, so I include the .LoadWith() to load the User with his list of roles when it serializes.
Jarrett makes some good comments about using database tables.
Just to answer another one of your questions, no, it's not a confidentiality thing to put your OpenID in your code generally. If setting up roles seems overkill for your site, a simple equality check against your ClaimedIdentifier is just perfect.

Resources