Role based Authorization on WebApi Controllers in IdentityServer4? - asp.net-core-1.0

If I have two .net core WebApi Controllers, AdminController and UserController (in one project). And both requires authorization then how can I set them as 2 scopes in IdentityServer4 so that Admin user would have access to both controllers but simple user could not access Admin controller but simple user controller only? My client is of Angular 2 type. And is there any example where Role based authorization is also shown ?
Thanks,Maverick

Not the definitive answer to your question probably (since it doesnt involve 2 scopes) - but it might lead you somewhere.
Im assuming your using the TokenValidation middleware, and that your api is setup using IdentityServerAuthentication
You can have a role claim, which indicates what role the user has (ie. user, admin).
Then you can put up a check on the role for the admin api using the [Authorize(Roles="admin")] attribute, and for the user api, just use [Authorize] which ensures that a user is logged in, or specify both roles as a comma separated list ([Authorize(Roles="admin,user")]) if needed.
i.e:
[Authorize(Roles="Admin")]
public class AdminController : ApiController
{
Here is a link to the docs on the Authorize attribute for .net Core:
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles

Related

Single app registration in Azure for mobile app calling own backend

I want to authenticate users with Azure Active Directory (AD) in a mobile app that calls its own REST API and possibly, make it simple.
Looks like the documented way (here or here) to do so is to
register the API app with AD, expose some scope(s) as delegated permissions
register the mobile app, add these scopes as API permissions to this app
do authorization decisions in the API app based on these scopes
Question:
Now, since I feel the front-end and back-end parts of my app should belong into the same "black box" plus there are no fine-granular user roles within the app that would justify usage of multiple scopes or require the user to consent to using them, I'm wondering whether there is a recommended (and secure) way to go with just one app registration instead of two?
What I tried:
When using Okta in a similar scenario, I only had one app (clientId) and the back-end configuration pretty much validated the JWT token issuer, domain and a default audience string (in my understanding). I tried inspecting tokens from AD acquired via the authorization code flow for usual scopes (openid profile) to see what their audience was and if this could be reproduced - this is what I've got:
the well known GUID of Microsoft Graph (for the access token) - this one doesn't feel "correct" to validate, as pretty much any AD user could present an access token for MS Graph and only assigned users should be able to use my app
client ID of the app (for the ID token) - but the docs says these should not be used for authorization, so not sure if it's a great idea to pass them as Bearer tokens to the API
The standard thing in OAuth technologies is to only register a client for your mobile app. Azure has some vendor specific behaviour when it comes to APIs, related to the resource indicators spec. When there is no API registration, your mobile app will receive JWT access tokens with a nonce field in the JWT header. These are intended to be sent to Graph, and will fail validation if you ever try to validate them in your own APIs.
If like me you want to stay close to standards, one option is to add a single logical app registration, to represent your set of APIs. You might design an audience of api.mycompany.com, though Azure will give you a technical value like cb398b43-96e8-48e6-8e8e-b168d5816c0e. You can then expose scopes, and use them in client apps. This is fairly easy to manage. Some info in my blog post from a couple of years back might help clarify this.
Now, since I feel the front-end and back-end parts of my app should belong into the same "black box" plus there are no fine-granular user roles within the app that would justify usage of multiple scopes or require the user to consent to using them, I'm wondering whether there is a recommended (and secure) way to go with just one app registration instead of two?
You can create just one app registration; in fact the newer app registration model was designed to do that.
In the case where an API is used only by the app itself, I would register a single scope, something like MobileApp.Access.
Your API should verify the presence of this scope to prevent unauthorized applications from calling it.
In addition to verifying the scope, you will need to verify user permissions.
And filter the data based on their identity, depending on your use case.
Your question seems to suggest that you might be mixing scopes and user roles.
Scopes are permissions given to an application.
Also called delegated permissions; they allow an app to do some actions on behalf of the signed in user.

Registering Admin in Nodejs

What I am trying to do is that, there is some Admin who has all the access to routes and also some routes where only he is allowed. So, this is one part.
Now, my question arises is that how someone can become a Admin, like who is actually a Admin.
There are some articles online where they mention that "Give a Role property, that can be from { 'user' , 'admin' }". But there is nothing stopping a normal user from becoming a Admin. So, how top Organizations or any, implements the Admin part considering security and trust models ?
So a user would sign up to your website using whatever you have. You would pass the JWT with the user identifier on each request to the API from the client as well as the session.
Your node.js API would have middleware to check if the user's session is valid and if the JWT is correct. Website -> Node.js App -> Middleware -> Protected Api Route. If you are using Express then you would call next() in your middleware function. If they are not authorized then you would use: return res.status(403).send({message:"Not Authenticated"})
Middleware
Inside your middleware, you would want to use some caching such as Redis to reduce the load on your server. You would also want separate middleware to handle rate limiting(if you need it). Another method would be calling your database instead of storing the data in the JWT itself. You would check the database by searching for the user identifier in the JWT after verifying it. There's the possibility for sessions but you can just get the role from the database if you aren't doing that.
You would either use a number-based system as an enum. An example of one:
0 - No access
1 - User
2 - Admin
Each route would specify a value see: Creating a expressjs middleware that accepts parameters on how to do it in Express. If the user role is smaller than the required role then refuse entry to the API route by sending a 403.
Give a role
You would have an API route that would give roles to people. You would also set in your cache the user identifier's role as well as in the database. I would only allow setting a role by roleNum - 1 as the max role that person can give. I would also either set a user as the super admin by the database itself or create a default user with the max role by default.
Remove a role
You would have another API route that would set the role to 0 or 1(basically the role you want to give).

Auth0 - Rules & Groups && User Management

I have created an account with Auth0 and I am trying to get a simple login for Angular 2 to our backend API.
1. What I am trying to do is to be able to access the roles in the API to see whether the user has the correct permissions.
I have enabled the Auth0 Authorization extension I have gone in and created one group and one role, I have assigned these to a test user which I have created, I have then gone to the configuration and published the rules for token contents and persistence.
How can I view the permissions/groups from the JWT in an nodejs app? I am using express-jwt and this:
const authenticate = jwt({
secret: config.get('AUTH0_CLIENT_SECRET'),
audience: config.get('AUTH0_CLIENT_ID'),
credentialsRequired: false,
});
Which is giving me details such as iss, sub, aud. But no details on the user metadata, how am I able to retrieve this? Also as I have clearly not used Auth0 before, is it best practice to store the user details on our own databases also so I can use my own ID to store against the user actions, or is it possible to use an ID if Auth0 give one to store against user actions in our database.
EDIT 1
Ok I can see there is an options parameter for the Lock which you can pass scopes in, is it bad practice to request these when logging in? There will only really be a handful of groups/roles for now. Or is better that the API can lookup the user using the token provided to get the app_metadata to view the permissions etc, if so how can I look this up?
2. How am I able to manage the users and view them so I can display them in our own admin panel and manage the permissions they have.
For the case where the groups and roles information are available within the token itself (as groups and roles claims) and given that you're using express-jwt then you can access this information on the server-side by accessing:
req.user.groups
req.user.roles
In essence, express-jwt will make the claims contained within the token available in the req.user object.
In relation to the ID you use to identify the user you can use the value contained within the sub claim of the user token. This value is guaranteed to be unique and stable so a recurring user that uses authenticates in exactly the same way will always have the same value within the sub claim.
You already discovered that one way to include the groups and roles information is to request it through the scope parameter. It's not a bad practice to request this information to be included in the token, however, you need to take in consideration that tokens delivered through the implicit grant which is used by SPA are included as a part of the callback URL and as such their maximum size is constrained by the limits imposed on URL's.
In regards to your second question, you could implement your own management backend by integrating both the Auth0 Authorization extension API and also the Auth0 Management API; see the following links for more info:
https://auth0.com/docs/extensions/authorization-extension#enabling-api-access
https://auth0.com/docs/api/management/v2

After UseOpenIdConnectAuthentication, how to put claims from Security Token into Controller.User (Current HttpContext) that are in OwinConext.User?

I have VS2013 MVC5 project with Individual User Accounts. I modified Startup {Configuration(IAppBuilder app)} so that UseOpenIdConnectAuthentication is the only allowed authentication.
Users can register in the AspNetIdentity DB using the out of the box MVC project template plumbing. After registration, Users login with OIDC.
The OpenID Connect STS (IdentityServer3 with AspNetIdentity) returns a security token with claims and roles. These claims are available from the authenticated ClaimsPrincipalin the Request.GetOwinContext().Authentication.User.
However these claims are missing from the Controller.User (Current HTTP Request context).
Is it a good thing to make the two ClaimsPrincipal match?
QUESTION: If so how and where do I do that? I'm not an expert and wonder what about OpenIdConnectAuthenticationNotifications.SecurityTokenValidated or
Application_PostAuthenticateRequest?
I realize this is a side-effect of mixing MVC5 System.Web with OWIN middleware for OpenIdConnect, rather than the default MVC5 project authentication middleware.
if you are working with ASP.NET 4.6 and Katana 3.x you should be able to access the claims you want from ClaimsPrincipal.Current.
See the comment below

How Custom membership provider can be used in Asp .Net MVC 5

I want to use my own table for user login and role in asp .net MVC 5. So that I can get Custom identity value in controller and can check authentication and authorization in controller.
I see these
http://www.dotnet-tricks.com/Tutorial/mvc/G54G220114-Custom-Authentication-and-Authorization-in-ASP.NET-MVC.html
http://blogs.msdn.com/b/webdev/archive/2013/07/03/understanding-owin-forms-authentication-in-mvc-5.aspx
but can not get good answer any body can help me?
Look at System.Web.Security.Membership
I would register the user on your database using EF then call the CreateUser Method with the creditentials.
You can then validate the user against your stored email/username and password
using the ValidateUser Method.
Hope that helps

Resources