I have a simple API which only support one role as of now.
I would like to add an admin role and a normal user. I'm using JWT to authenticate and I have a roleName in my claims.
Now, I would like to have one route for some of my endpoints, but based on what role the user logged in with, the controller corresponding to either admin or user is selected and executed.
Simple example
As a normal user:
/v1/members
returns
{
"memberId": int,
"name: string,
"address": string
}
If the admin user logs in, I would like to have the same url /v1/members, but with another return
eg.
{
"memberId": int,
"name: string,
"address": string,
"socialSecurityNumber": string,
"privatInfo": string,
"notforuser": string
}
I know I could do it in one controller and switch out the roles, but it makes my code very messy and I don't think that's the way to do it.
Best regards from Jens
I'm just gonna answer my own question.
After some hours researching I finally found a solution, that I think works great.
In stead of hooking into the convensions as such I define a middleware, that runs before the MVC actions. It rewrites the local url for the controller and then it hits the correct controller and it's split into separate areas. It works great.
Best regards
Jens :-)
Related
We have a monolith application and looking to decouple the authentication / authorization service.
At this stage, authorization is the simplest to start with.
The problem comes with authorizing certain type of access to resources. e.g. a user can edit only his own posts.
Given that the microservice will hold only roles/auth items and assignments to an user id, does it make sense to create the following endpoint?
POST v1/<userEmail>/authorize/<authItemName>
with data, e.g.
v1/user#company.com/authorize/Posts.UpdateOwn`
{
post: {
content: 'My first post'
...
creator: {
email: user#company.com
}
}
}
Where we would send the object's data and the user's data. That way I can have a rule that would return true if object.creatorId === userData.id however if you think about it, it seems pretty dumb... if the monolith already has the info, why not just check for
the general permission Post.Edit and also checking that the user is the creator.
Is there a better approach for this?
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.
My first question here. For an MVC 4 CMS application that I am building, I am making use of the SimpleMembersshipProvider. In it, I have users that are assigned to specific roles. Upon login, I want to check what role these users have, and then redirect them to their specific part of the application.
So when the user logs in, I check using:
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
if (User.IsInRole("Organisation"))
{
return RedirectToAction("Index", "Organisation");
}
}
This never works the first time around, but as soon as I type in the URL after the code has executed, or if I do this a second time, it works perfectly. Is the Role information not available upon login? Is there another way I need to handle this perhaps?
Thanks for your answers and my appologies if this is an easy question.
you have to write that if section after redirection. roles don't work before page refresh.
I'm trying to find a way to modify a web page based on the a user's authorization. For example, the owner of a resource should see edit and delete buttons while a regular user should not see those.
The following is a method I am thinking about, but am unsure if there is a more common/better way.
For example, assume there is a resource
project: {
name: string,
owner_id: id,
moderators: [ids],
other_stuff: string
}
Would it be RESTful and good practice to extend this object with an attribute that describes what role the current logged in user is? For example, assuming this user is one of the moderators, it'd send
project: {
name: string,
owner_id: id,
moderators: [ids],
other_stuff: string,
user_role: "moderator"
}
Then the client-side framework would use project.user_role to display role-based controls such as delete and edit.
[Problem]
I have a pre-built database with user credentials. The only thing I can change about this database is how the passwords are hashed. (Don't ask about that...let's just say it's dumb and I'm fixing it, please.) It's populated with credentials, so whatever I use has to mold to it. We are switching to the ASP.net MVC4 framework, and starting from scratch.
[Question]
What membership system should I use for the problem, if any?
It should:
a) allow me to check against the database using SHA512 for the password
b) set roles depending on the results
c) decorate the actions in the controller so I can feel like a boss
[Details]
Assume I've had a website for people who love to roleplay as toothbrushes. There's -a lot- (for a small- to mid-range website) of data already in the existing database. I'm moving to a brand new database layout and will be converting from the old one. We could change how the user system is managed, but to be honest we'd rather not do so. We have a user table with username and password. Very simple.
I have googled, and googled, and Stack Overflow'd, and Stack Overflow'd. What I have found is essentially a choose-your-own-adventure book where they either have blank page numbers, or the give me a page to an older book whose adventure isn't quite like this one.
I'm hoping that either a) someone will call me a dumb butt and point out I'm asking a duplicate question that leads to a resource with some complete example and/or documentation on how to do what I want or b) help me find a way.
As of right now I'm contemplating writing my own user management/authentication filtering system. I was going to go with the MembershipProvider but that seemed like overkill and didn't appear to do what I wanted it to. Maybe I'm narrowing my vision down too much.
I'm more than willing to hack my own way through and work to solve a problem, but I don't want to roll my own thing if there is something available that I can hook in to.
Update 1
Win made a comment about the MembershipProvider being independent of the MVC system which gave me an "Aha!" moment as things come together. I'm re-evaluating my research to see if I simply didn't put the puzzle pieces together correctly.
Update 2
After much help from dkroy and Win, I got a bit deeper into what is going on here. Once I have everything done I will include it in an edit for anyone else looking for information. Essentially, I was on the right track before I was thinking about scrapping it. I hadn't implemented a GetUser call, and I wasn't calling SetAuthCookie, so it wasn't working correctly. I'm now in the process of writing a RoleProvider.
a) allow me to check against the database using SHA512 for the password
Membership provider support SHA512.
b) set roles depending on the results
c) decorate the actions in the controller so I can feel like a boss
If you want to restrict user by role, you want to implement both Custom Memebership Provider and Custom Role Provider.
However, you do not need to override all. Here are the main ones -
// Membership provider
public override bool ValidateUser(string username, string password)
public override MembershipUser GetUser(string username, bool userIsOnline)
public override string GetUserNameByEmail(string email)
// Role provider
public override bool IsUserInRole(string username, string roleName)
public override string[] GetRolesForUser(string username)
You can Create your own custom RoleProvider and MembershipProvider. That way you will be able to use your existing database structures, and still leverage the MembershipProvider and RoleProvider contracts that ASP.NET implements to provide membership services. Minimal searching on custom MembershipProviders should get you started.