I have a Web API project of ours that needs to be secured. I am planning to allow the user's that registered with my app to use the API [Forms Authentication], users with their own organizational accounts [ADFS] and Social Sign-In.
I have all the middleware available to plug-in and make available to the user's. However, in my application I do have custom roles and privileges that are to be provided so that my application authorizes the service calls based on the existing privileges. What is the best way to accomplish this.
I think that I will be required to provide my own custom implementation of the UserStore and UserManager with my own IUser Implementation.
Kindly suggest the best practice for this scenario.
With multiple authentication middleware registered, you can get multiple claimidentity's.
register each type of authentication you want to support.
I would be sure to add a claims transformation module at the end of the pipeline. Thinktecture has an example. ThinkTecture Owin Claims Transformer
This would give you one place to look up and add all the application type claims for an authenticated user in one spot.
Simple pseudo example (geared to webapi, but concept the same). Authenticate with bearer or basic or both then transform.
//identity 2.0 user manager stuff used in your modules
app.CreatePerOwinContext(ApplicationSession.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Token Authentication -> get a principle
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
// Basic Authentication. -> get a principle
app.UseBasicAuthentication(app.CreateLogger<BasicAuthenticationMiddleware>(),
"Realm", ValidateUser);
// transform claims to application identity. Add additional claims if needed
app.UseClaimsTransformation(TransformClaims);
It sounds like you are looking for externalized authorization. Externalized authorization is the act of:
decoupling business logic from authorization logic
expressing authorization logic as centrally managed, centralized authorization policies
protecting your APIs through a common layer
enabling fine-grained & dynamic access control through the use of attribute-based access control (ABAC) which extends what's possible with RBAC (role-based access control).
Have a look at XACML, the eXtensible Access Control Markup Language. You can find some more information on OASIS's website.
Also check out NIST's project on ABAC.
Once you defined your authorization logic, you can decide how to enforce it. This can be done either via direct enforcement at the entry of your apps or can be done in a provisioning way whereby the permissions derived from the authorization policies are fed into an authentication token e.g. SAML as attribute assignments.
HTH
This is what I ended up designing for a system with similar requirements. The key is to separate the authentication and authorization logic.
Build Owin authentication middleware components that take care of establishing user identity based on various login methods you mentioned. Looks like you have this accomplished. Set ASP.NET identity based on the user.
Retrieve the roles/permissions for the logged in user from your store. This can be done as a separate Owin middleware or a part of your authentication. Add the permissions as Claims to your Principal.
Extend your roles/permissions store to map API service operations to the application permissions.
Implement a custom API Authorize attribute and apply it to every API operation. In this attribute you will have access to the operation name and the user Claims (permissions). Match the Claims with the permissions you mapped in the step above. If there is a match, return IsAuthorized=true, otherwise, return false.
Here is a similar issue at a simpler level.
How do you setup mixed authorizations for different authentications in .net (web api 2 + owin)
Related
I have an ASP Net Core Web API which uses auth0 for authorization and authentication. Moreover, every endpoint is protected with different scopes. For example, to access the endpoint to read all reservations, one would need to have the read:reservations scope.
In auth0, I have roles that contain multiple permissions. Currently, I have an admin role that has access to all endpoints and a receptionist who can only view and edit reservations.
I want to create some integration tests to verify that the authorization works. I am using the Client Credentials Flow as explained here. The problem is that the access tokens I get have no scopes and, therefore, cannot access the endpoints.
At the end of the linked article, it is mentioned that the tokens can be customized using actions. However, I am confused because, as far as I understood, I would have to add every permission manually.
My question therefore is, how could I create multiple access tokens for the different roles that I have to test the endpoints as if I were a person with a said role?
We are building an application where the content i.e. data and files would need granular user access the way role and policy works. We use oAuth2 and OpenID connect using one identity provider.
My question is about the possibility of leveraging a platform or AWS Cloud service where this type of granular authorization is available. I don't want to build custom authorization matrix within my application, rather I prefer to use an API of a service and user role/policy for further actions.
When it comes to using scopes from OpenID connect, they are more suitable for defining API level of access.
I would start with your requirements, such as users only being able to only see their own data. Fine grained authorization is typically managed via claims in tokens, which can be highly dynamic when required.
See this Claims Best Practices article for some details. It mentions some specialist authorization systems also.
Cloud solutions may at times be more focused on infrastructure security whereas OAuth deals with application and user level security.
Having said that, defining resource policies as JSON documents like AWS does could be a useful declarative technique to complement claims. At runtime you could then compare a claim from a token, eg a role, against the resource policy to see if the user should be granted access.
I have the following projects:
Identity Server 4, with ASP.NET Identity as a user store for all users of all my apps.
.NET Core 5 Web API
Xamarin app
The flow goes like this:
User logins from the Xamarin app (3) and is authenticated against IdentityServer (1)
User receives an access token from Identity Server, that contains the sub claim
User makes a request to the Web API (2) using the access token
The Web API (2) checks its own database for user permissions
----QUESTION/PROBLEM IS HERE-----
Should the Web API add these user claims (permissions) to the access token, OR should the Web API always check the database for the user permissions on every request made from the client?
Maybe I could add the claims before authenticating with IdentityServer, but this would mean that IdentityServer would have access to the Web API's database. I believe this is not a good practice because of separation of concerns.
Another solution would be to introduce a caching mechanism when the Web API validates the token, so that it doesn't always check the database.
Using claims transformation, it is my understanding that I can add the claims to this 1 request only, meaning that the next time a client makes a request, claims transformation should happen again, since it doesn't return a new access token to the user.
Ideally, I would like the Web API to add the claims to the access token so that the Web API can trust these claims on all subsequent requests. I cannot find a way to do so, though. I've searched for Claims Transformation, IssueJwtAsync (IdentityServerTools), IProfileService, but I think none of these are solutions to this problem.
Is this good architecture? Please do share your opinions on this subject and potential solutions.
Thank you very much!
You need to add these permissions in web api, because users need to access the corresponding resources according to these granted permissions. And permissions are granted when the user logs in for the first time, without the need to access the database in every request.
In this case, you can use Claims Transformation. This link has more detailed steps which can solve this problem.
I'm currently trying to migrate a multi-tenant system from a "custom" authentication and authorization implementation to OAuth2.
The multi-tenancy model is very similar to GitHub's structure, so I'm going to use it as the main example. Let's assume that in the application we have users, repositories and organizations. Users have access to repositories directly, or through organizations they are members off. Depending on their access rights, users should have different permissions towards repositories and the sub-resources (like /repository/issues), or organizations and their sub-resources (/organization/members) for users who manage them. Unlike, GitHub's OAuth2 solution, this system should be able to provide different levels of permissions across repositories or organizations (GitHub does it at a different level with a custom implementation).
The goal is to keep the logic as simple as possible, encapsulate everything in an authorization service and piggyback on OAuth2 as much as possible.
My approach was to deploy a generic OAuth2 service, and handle the permissions using dynamic scopes:
user:read
user:write
repo:read
org:read
repo:<repo_id>:issues:read
repo:<repo_id>:issues:write
org:<org_id>:members:read
org:<org_id>:members:write
This enables granular permissions for clients and users, such as a user being able to read + write issues in one of his repos, but only read in another.
While this seems to solve the problem, the main limitation is being able to request scopes. Since users would not know the ids for the repos and orgs they have access to, they are not able to request a correct list of scopes when contacting the authorization server.
In order to overcome this I considered 2 solutions:
Solution 1
Issue a token for repo:read and org:read
Retrieve list of repos and orgs the user has access to
Issue a second token with all necesarry scopes
On a deeper thought, this turns out not to be viable since it would not support grants like implicit for authorization_code unless the authorization server would deal with this "discovery" of resources.
Solution 2
The first 2 steps are common to the first solution, while for the 3'rd step, the users would only be able to issue tenant scoped tokens. By extending the OAuth2 with a parameter identifying the tenant (/authorize?...&repo=<repo_id>), clients using authorization_code grant would have to issue tokens for every tenant. The token issued on step 1 would have to persist the identity of the user on the authorization server and eliminate the need of re-authentication when a user would switch between tenants. The downside of this approach would be that it increases the complexity of client integrations and that it might defy the standard in some way.
I'm looking for a second opinion on this, which would possibly simplify the problem and make sure the solution adheres to the standard.
tldr; What about using self contained access tokens which convey user identity information and hold access policy defined at API endpoint ?
The problem you face right now is due to mismatch of what OAuth 2.0 scope is capable of. Scope value in OAuth 2.0 is defined to be used by the client application.
The authorization and token endpoints allow the client to specify the
scope of the access request using the "scope" request parameter.
But in your approach, you try to make it to be defined by end user (the human user).
A solution would be to make authorization server independent of permission details. That means, authorization server only issue tokens which are valid for your service/system. These token can be self-contained, holding user identifier and optionally organisation details (claims). It may contain other details that are required by your service (upto you to decide). Ideal format is to make it an JWT.
Once your client (the consumer of system, like GIT website) obtain this token, it can call the system backend. Once your system backed recieve the token, it can validate the token for integrity, required claims and use these claims to identify what resources are granted for this specific user. Permission levels you defined for scope now are stored with your service backend.
Advantage of this is the ability to let user identity to be reside anywhere. For example you can use Google or Auzure AD and as long as they can provide you a valid token, you can support such users to use your system. This is ideal as permissions are not stored in them. And super users will have ability to define and maintain these permissions.
Agree with everything mentioned by #Kavindu Dodanduwa but would like to add some additional details here.
This problem indeed stays beyond what standard OAuth 2.0 covers. If you want to manage permissions per-resource (e.g. per repo or organization) this should be handled in your service or a gateway in front of it. Typically you need some kind of access-control list (ACL) stored on your backend which you can then use to authorize users.
If you'd like to look at existing standards check out XACML and UMA (which is an extension of OAuth 2.0). However I find them rather complicated to implement and manage especially in distributed environment.
Instead I'd suggest an alternative solutions using a sidecar for performing authorization on your service. Check out related blog posts:
Building a fine-grained permission system in a distributed
environment: Architecture
Building a Fine-Grained Permissions
System in a Distributed Environment: Implementation
Open Policy Agent could be a good solution for such architecture.
We have a client with following existing product line
Website1 (Uses form authentication using user information stored in SqlDB for website1)
WebSite2 (Uses form authentication using user information stored in SqlDB for website2)
WinApplication1 (uses Active Directory to authenticate user)
More products in line for future release.
They want to implement Single Sign on (SSO) for all their products with following features-
Product list that will be accessing by a user will be depended on his/her role.
It should be configurable. Roles are being defined in DB having Fk relation
with user table.
SSO service should be flexible to accommodate new product.
should use SAML to sucure token.
WinApplication1 has link for website1 and website2. If an user is login in WinApplication1
and click on any links of website1/website2, user should able to access the sites without
entering his credential.
If user is logned in in any product that user should be all to access any other product
he has access right without enterting userid/password.
We have following query
We are planning to implement SSO using WCF and WIF. Can all above requirement be fulfill
by using WIF.
We want to keep user authentication part in respective product as each product has their
own user store. OR WE SHOULD HAVE CENTRALIZED USER STORE?
What shouldl be the responsibility of STS (implemented in WCF) in respect to SSO &
security?
We have read lot about WIF from MSDN(http://msdn.microsoft.com/en-us/library/hh377151(VS.110).aspx, http://msdn.microsoft.com/en-us/security/aa570351.aspx) could not find any solid article/sample giving some practical scenarios. Most of them about using local STS…may be it is my bad luck.
I found a article that matches most of your requirements with practical implementation example.
The article describes an easy approach for programming against Windows Identity Foundation in a Single Sign-On (SS0) scenario from the angle of a relying party application. WIF supports a variety of Claims-based authentication scenarios but this document will focus upon using WIF to develop an application that supports SSO given the use of a SAML 2.0 token containing some basic claims.
Article also includes some part explaining about using roles in AD Users:
http://www.c-sharpcorner.com/UploadFile/scottlysle/windows-identity-foundation-and-single-sign-on-sso/
To impersonate the Original Caller in WCF Calling from a Web Application, you additionally need to follow:
http://msdn.microsoft.com/en-us/library/ff650591.aspx
Update:
difference between IP-STS and FP-STS and how to choose where to put STSes in your architecture. You will learn about federation, home realm discovery and how to leverage the WIF extensibility model in order to handle multiple identity providers.
http://bit.ly/bTo3w4
How a generic web site can be enhanced with identity provider capabilities regardless of the authentication technology it uses, simply by adding an STS page.
Another lab shows how to use an existing membership store for authenticating calls to a custom STS and sourcing claim values.
http://bit.ly/bQAQhA
WIF and WCF
http://bit.ly/8X63T5
Hope it helps.