SimpleMembershipProvider roles not accessible - asp.net-mvc-4

I have MVC4 application which uses SimpleMEmbershipProvider for authentication mechanism.
Everything works fine, apart of when I return to the application and authenticate using persistant cookie.
I am authenticated fine, but cannot access roles that I am assigned to. Effectively, cannot access roles at all:
string.Join(",", Roles.GetRolesForUser(User.Identity.Name))
returns empty string
What might be causing that?

This can happen when the SimpleMembershipProvider hasn't been initialized. The example MVC forms authentication template assumes that you'll be allowing anonymous access to your site and doesn’t initialize the membership provider until you go to the login page. However, a more common security technique is to require a login for any site access and to define menu choices in the _layout page to be determined by roles. But, if you use the persistent cookie, you don’t revisit the login page so the roles for the authenticated user aren’t loaded from the membership database.
What you want to do is initialize the provider when the user enters the site so that values get loaded. To do this, you want to add the following filter in the RegisterGlobalFilters method of the FilterConfig class in the App_Start folder
filters.Add(new YourAppNameSpace.Filters.InitializeSimpleMembershipAttribute());
This will cause the user data to be loaded from the database when a cookie authenticated user enters the site.
Another alternative technique is to add the [InitializeSimpleMembership] decorator to any controller method that cookie autheticated users might enter directly. This is kind of messy though if you have to put it on a lot of controllers. Therefore, putting it in the global filter is better in most cases.

Related

Pass attributes to sec$User entered in the Coustmer entity creation screen [cuba-platform]

I'm new to Cuba-platform version 6.10.3. I have a problem where I am stuck.
I have a User entity where I create a new user which has parameters identical to those of the sec$User system entity. Now, I would like to pass the values ​​entered in the User entity (name, password, lastname, email) and also the access group created specifically for the users (customers). Then register the attributes directly in the sec$User system entity and then log into the app with the credentials of the users created with their respective permissions.
I hope someone can help me. Thanks a lot to everyone.
In order to create a new sec$User entity, invoke the Metadata#create() method of the com.haulmont.cuba.core.global.Metadata bean.
Fill necessary fields.
To save new user to the database, use DataManager bean: com.haulmont.cuba.core.global.DataManager#commit(user)
If you need to login to the application automatically without having user password, you can use the "trusted login" feature.
When in web client, user com.haulmont.cuba.web.Connection bean to login.
When in web service (e.g. portal module) - use the com.haulmont.cuba.security.auth.AuthenticationService service.
And call its login method with TrustedClientCredentials:
#Inject
com.haulmont.cuba.web.auth.WebAuthConfig webAuthConfig;
// ...
authenticationService.login(new TrustedClientCredentials("username", webAuthConfig.getTrustedClientPassword(), Locale.ENGLISH);
See also
https://doc.cuba-platform.com/manual-6.10/login.html#login_additional_eatures
https://doc.cuba-platform.com/manual-6.10/web_login.html
Note that web client is working under the anonymous user until other user logs in. So you will need to add additional permissions to the user (write access to the User entity).
Thanks for the support, very helpful !

ASP Net MVC Core - Load User Data From Active Directory when User browses Any Page

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.

Scope and Claims (again!)

I'd like to ask a question to confirm my understanding of how to use Scopes and Claims (roles). Let's say I have a User (User A with read only rights i.e. suitable read only role), a Windows Service (Client A with read only access), an MVC site (Client B with full access), and a Web API. I want the Web API to be accessed by Users and Clients with full access and read only access.
I create two Scopes "sampleApi.full and "sampleApi.read_only"
I create two Roles "full_access" and "read_only"
I configure the Web API with RequiredScopes = new[]{"sampleApi.full", "sampleApi.read_only"}
When Client A connects to the Web API, it passes an Access Token containing Scope "sampleApi.read_only" and I can use [ScopeAuthorize("sampleApi.full)] or ScopeAuthorize("sampleApi.full, sampleApi.read_only")] on my Classes and Methods to fine tune accessibility. No problem.
However, when User A logs in, then he/she "inherits" the Scopes of Client B. So the Access Token contains "sampleApi.full", "sampleApi.read_only", and Role "read_only".
Now I have a problem at the WebApi in that I need to act differently when being called by a User. In that case I ignore the Scopes and use his/her Roles and the User gets "read_only" access which is what I want.
That being correct, it no longer makes sense to use the ScopeAuthorize attribute, and I need a custom hybrid attribute that does something along the lines:
If Caller is a User
- then use Roles to determine accessibility
Else
- use Scopes to determine accessibility
or have I completely misunderstood?
Scopes model what a client (not user) is allowed to access. They are manifest as claims in the token. The user's claims are also in the token. Authorization in the resource will be based on a combination of what the client is allowed to do and what the user is allowed to do. That's it.

From where knows [authorize] the roles / users (ASP.NET MVC 5)

I'm a newbie to asp.net mvc, so I created a simple internet application from the template. I added some user and some roles and connected them (in database). Then I added [authorize(Roles = "MyRole")] and everything works fine. Can anyone tell me from where authorize takes the information about users and roles and so on? Where is the magic that wired that up? (As I said: simple application from template mvc 5 "internet application")
There's not really any magic here. Once you've authenticated, a principal is registered and filled with some of the basic information for the user, including any roles they're associated with. This information ultimately comes from your database of course, but how the authorization layer retrieves that and implements the principal from it is low-level and dependent ultimately on the authentication provider being used (Membership, Identity, Windows Auth, etc.).
Regardless, the Authorize attribute merely looks at the roles on the principal and if there's a match, allows the action to proceed. Otherwise, it does a redirect, usually to the sign in page of the application, or returns a 401 Not Authorized, depending on whether the user is authenticated or anonymous.

Custom PrinciplePermission Authentication

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.