I am not sure about BuildVirtualUser method behavior in Sitecore 6.6 update 3
I have the following code:
bool isAuthenticated = true;
string userName = string.Format("{0}\\{1}", "extranet", user.Login);
SC.Security.Accounts.User virtualUser = SC.Security.Authentication.AuthenticationManager.BuildVirtualUser(userName, isAuthenticated);
but after BuildVirtualUser method call virtualUser variable contain all extranet roles.
I expect that just my following code should attach role to user.
foreach(var role in user.Permissions)
{
string domainRole = string.Format("{0}\\{1}", "extranet", "USER_EDIT");
if (SC.Security.Accounts.Role.Exists(domainRole))
{
virtualUser.RuntimeSettings.AddedRoles.Add(domainRole);
}
}
Why does it happening? What do I need to do to fix it?
Update 1
I have discovered that first time BuildVirtualUser creates user with 0 roles,
roles can be succesfully added, but after logout and login procedure with the same user name, roles that were added during first time automaticaly attaching to new user. In my opinion this bahavior is not good, in case someone can edit user roles in external system.
Try this:
user.Roles.Add(Sitecore.Security.Accounts.Role.FromName(domainRole));
from:
http://sdn.sitecore.net/upload/sitecore6/sc61keywords/security_api_cookbook_usletter.pdf
I am not sure what your for each loop is, but it's kind of redundant your not doing anything with each 'role'.
SC.Security.Accounts.User virtualUser = SC.Security.Authentication.AuthenticationManager.BuildVirtualUser(userName, true);
virtualUser.RuntimeSettings.AddedRoles.Clear();
virtualUser.Roles.RemoveAll();
this code is help to update user roles dynamicly.
But I still not undetstend why sitecore cache roles for virtual users.
Related
I was looking for simple Laravel 5.6+ version roles and users solution.
I want to have one users table. So I added user_type in my table as string in
$table->enum('role', ['admin', 'user']);
Which files should I create or update to protect everything under /admin route. And do not let to use admins routes for users?
You should create a middleware that is active in all /admin routes. In this middleware you should check if the user that is logged in (Auth::user()) has the "admin"-role.
Auth::user() references the User-model.
So in the User-model you can create a function like isAdmin():
public function isAdmin()
{
return $this->role === 'admin'
}
In the Middleware (or wherever you want it) you can just write
if(Auth::user()->isAdmin()) {
// do something if user is admin
} else {
// do something if user is not admin
}
Since it is in the User-model you can also write $user->isAdmin() for regular user models.
I am using Facebook as external login of ASP.Net Core identity.
I would like, even if the user logged in with Facebook, the user to fill his profile on the website.
For that I use the ExternalLoginCallback method, from which I would like to get data from Facebook such as date of birth, location (country), ...
One issue is if the user unchecked some of the permissions, the default call to Facebook fails:
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
return RedirectToAction(nameof(Login));
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
I would also need to do some additional checks on user data, which would require calling directly the Graph API.
My blocking points:
- In the ExternalLoginCallback method, I would need to separate the 'country' and 'birthday' to avoid the Facebook API to return an error in case of the user didn't grant the permission
- For that I would need the the user access_token (and for additional calls in the method), I don't see how to get it even if it is used by the Facebook Identity framework
- Once the profile created, I would like to get access to this access_token, which should be stored in the UserTokens table (I guess?), but I can't find it there, the table is empty. (my DbContext is a class extending IdentityDbContext<AppUser, AppRole, long>, don't know if it has an impact)
I have found this answer https://stackoverflow.com/a/42670559/4881677 which may help, but not sufficient.
Any help? :)
In order to store the user Facebook token, it requires to specify it in the options (not stored by default).
var fo = new FacebookOptions();
fo.SaveTokens = true;
From there we can call the graph method permissions to get the available permissions: https://graph.facebook.com/me/permissions?access_token={token}
Then it can be read with something like this:
foreach (var perm in data)
{
perms.Add((string)perm["permission"], (string)perm["status"]);
}
I need to validate user credentials from external service, therefore I'm using the VirtualUser authentication.
BuildVirtualUser, checking for the roles to set to him, saving the user Profile and then login with that name.
I'm facing a problem, that everyday that i login, with the same credentials Sitecore creates a new user in Experience Profile.
What i need to change in my code to assure that, with virtual user login, Sitecore gets the old experience profile of the user?
I was thinking in creating the user in sitecore with same generic password. Instead of using the virtual user, and authenticate directly with sitecore. Is that correct?
Here's my code:
Sitecore.Security.Accounts.User user = Sitecore.Security.Authentication.AuthenticationManager.BuildVirtualUser(sitecoreUser, true);
string roleName = #"newRole\User";
Sitecore.Security.Accounts.Role demoRole = Sitecore.Security.Accounts.Role.FromName(roleName);
if (Sitecore.Security.Accounts.Role.Exists(roleName) && !demoRole.IsMember(user, true, false))
{
user.Roles.Add(Sitecore.Security.Accounts.Role.FromName(roleName));
}
user.Profile.Name = name;
user.Profile.Email = email;
user.Profile.FullName = fullname;
user.Profile.Save();
Sitecore.Security.Authentication.AuthenticationManager.Login(user.Name);
Tracker.Initialize();
Code looks fine, but you miss one important thing: to identify your user/contact.
You need to add next line of code:
Tracker.Current.Session.Identify(email);
Please check next link to find more information about how to identify contacts:
https://doc.sitecore.net/sitecore_experience_platform/setting_up__maintaining/xdb/contacts/identifying_contacts
We use sitecore to manage our registered users (extranet domain) and when creating new virtual users we give it an email using the Profile.Email property and then call the Profile.Save() method.
Another property somewhere else reads the userProfile.Email, everything is fine at the beginning.
Plus we use Forms authentication with the remember me feature.
The problem is when we close the browser and reopen it Sitecore.Context.User contains info about the actual user who clicked remember me but the User.Profile always has the Email null.
I tried Reload() and initialize() they don't work. I also tried getting the user again via the username (User.FromName()) but the returned user object also doesn't have the Profile Email.
What is being done wrong?
There is one very important remark in Security API Cookbook. It is related to Sitecore 6 but as far as I know it should work with Sitecore 8 as there was no important changes in Security model. It worked for Sitecore 7.
Important You must log in a virtual user only after you assign Roles and Profile properties to them. The Roles and Profile properties that are assigned after logging in are lost upon subsequent request.
Sitecore.Security.Accounts.User user =
Sitecore.Security.Authentication.AuthenticationManager.BuildVirtualUser(#"domain\user"
, true);
if (user != null)
{
string domainRole = #"domain\role";
if (Sitecore.Security.Accounts.Role.Exists(domainRole))
{
user.Roles.Add(Role.FromName(domainRole));
}
user.Profile.Email = "user#domain.com";
user.Profile[“Custom Property”] = “Custom Value”;
user.Profile.Save();
Sitecore.Security.Authentication.AuthenticationManager.LoginVirtualUser(user);
}
Hi
I am devolping an application with multiple sites and each site has their own extranet, and this is all working beautifully, using Sitecore 6.4.
Now I need the editors (not admins) of each site to be able to create extranet users that is only able to access the extranet connected to the site, is this even possible?
Basically I am looking for at structure like this:
Sitecore\Editor (Local extranet admin)
Extranet\user
I would think you could make an Extranet Role for each of you "extranets", eg. Site1Admin.
And then make a page that enables them to create a user, giving that user the basic roles it needs.
This is code for Sitecore 6.0, though it should be the same for 6.4 afaik:
Sitecore.Security.Accounts.User user;
if (!Sitecore.Context.IsLoggedIn)
{
string domainUser = Sitecore.Context.Domain.GetFullName("youruser");
string txtPassword = "yourpass";
string txtEmail = "youremail";
if (Sitecore.Security.Accounts.User.Exists(domainUser))
return;
MembershipCreateStatus status;
Membership.CreateUser(domainUser, txtPassword, txtEmail, "Never?", "Always!", true, out status);
if (!status.Equals(MembershipCreateStatus.Success))
{
throw new MembershipCreateUserException(status.ToString());
}
user = //something to load the user, probably in Sitecore.Security.Accounts.User
}
var role = "extranet\\Site1User";
var roles = Roles.GetRolesForUser(); //this is probably only for the current context user
if (!roles.Contains(role))
{
try
{
Roles.AddUsersToRole(new string[] { "youruser" }, role);
}
catch(System.Configuration.Provider.ProviderException)
{
// do nothing, just move on
}
}
}
This is kinda simple, is based on some code I tried to hack together from some working code, that created a user and logged him in and should be adjusted to what you are doing, as there are probably some errors.