Call Profile Provider By Name in Profile config - sitecore

I have a legacy system (sitecore 6.1) which is already have one profile provider in plave as default profile for admin section.
Now, i need to impelement another customised SQL profile provider (in a different table) for normal user.
But my question is How dose system know which profile provider to use in code?
Is there any thing I can do similar as :
System.Web.Security.Membership.Providers[providerString];
So that I can call customised profile provider in my code accordingly.
Or what would be the best practice in this case.
I've wasted like 1 hour try to go through sitecore docs, but not much available there.

Here's some code that I recently did to set up some custom profile stuff for a client using the Email Campaign Manager. Granted this code uses some classes specific to ECM, it creates a new user, initializes a profile class and then assigns that profile to the new user. Then it sets some custom properties for the user that was just created. It shows you how to call the profile based on the user as well as assigning a profile to use for that user. This might help or maybe help someone else.
public static void Process(List<Subscriber> userItems, Item targetAudienceDefinitionItem)
{
foreach (Subscriber user in userItems)
{
// you can also just pass it the id of the target audience as a string
Sitecore.Modules.EmailCampaign.TargetAudienceBase target = Sitecore.Modules.EmailCampaign.TargetAudience.FromItem(targetAudienceDefinitionItem);
string campaignname = target.ManagerRoot.Settings.CommonDomain;
string realUsername = campaignname + "\\" + user.UserName;
using (new SecurityDisabler())
{
User newUser;
if (!Sitecore.Security.Accounts.User.Exists(realUsername))
{
// create a new user and assign it to the email domain specified in the manager root item
newUser = Sitecore.Security.Accounts.User.Create(campaignname + "\\" + user.UserName, System.Web.Security.Membership.GeneratePassword(8,1));
}
else
// get back the existing user
newUser = User.FromName(realUsername, false);
// get back the current user profile
UserProfile subscriber = newUser.Profile;
// reset the profile to be the profile specified in the manager root
subscriber.ProfileItemId = target.ManagerRoot.Settings.SubscriberProfile;
subscriber.Save();
// built in properties are set like this
subscriber.Email = user.Email;
// set custom property value
subscriber["Address"] = user.Address;
// or long method
subscriber.SetCustomProperty("Address", user.Address);
subscriber.Save();
// now subscribe the user to the target audience subscriber list
target.Subscribe(Contact.FromName(newUser.Name));
}
}
}

Related

Sitecore Virtual User Login Experience Profile

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

Using SitecoreUser.Profile with Forms Authentication

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);
}

Sitecore8 social connect does not import configured Facebook profile properties

According to this article:
http://techmusingz.wordpress.com/2014/07/03/social-connected-with-sitecore-facebook-2-access-facebook-information/
I should get the properties configured in Sitecore.Social.ProfileMapping.Facebook.config imported to the SC User Profile:
All I get however are these:
fb_basicData_id: 100001964217563
fb_basicData_email: <hidden>#hotmail.com
fb_basicData_appKey: <hidden>
fb_basicData_appSecret: <hidden>
fb_basicData_accessTokenSecret: <hidden>
fb_lastRenewed: 20150106T013821Z
fb_fieldsLastRenewed: 20150105T234345Z
How do I get the other properties to populate?
Starting from version 3.0, Social Connected stores social profile fields in Sitecore xDB contact facets. This is why you don't have them in user profile.
To get the required fields, you should use Social Connected API. Particularly, you should use the GetSocialProfile method of the SocialProfileManager class to get social profile of a user in a specific network. And then you will have access to all social profile fields in the Fields property of the social profile. Example:
var socialProfileManager = ExecutingContext.Current.IoC.Get<ISocialProfileManager>(); // or create it directly: new SocialProfileManager();
var socialProfile = socialProfileManager.GetSocialProfile(“userName”, “Facebook”);
var facebookGender = socialProfile.Fields[“fb_gender”];
I've struggled with the same issue on Sitecore 8.
Indeed the basic data from facebook is available from the GetCustomProperty function, but the rest of the profile data is later retrieved & made available under the SocialProfileManager.
For this class to be available remember to reference the Sitecore.Social.Api.dll and Sitecore.Social.Domain.dll in your project.
After that f.e.:
string facebook_email = Sitecore.Context.User.Profile.GetCustomProperty("fb_basicData_email");
if (!String.IsNullOrEmpty(facebook_email))
{
email.Text = facebook_email; // update UI here
}
var socialProfile = new SocialProfileManager();
// Do we have an extra profile from the user?
if (socialProfile.SocialProfileExists(user.Name, "Facebook"))
{
var facebookProfile = socialProfile.GetSocialProfile(user.Name, "Facebook");
if (facebookProfile.Fields["fb_first_name"] != null)
{
// do something here
}
}

Rest Replay Attacks / Security

let me describe a simple scenario:
There is a rest resource represented by this URI: /api/messages/{userid}. After the user is logged in, a request is dispatched passing to this URI "userid" (logged user). This way, as soon as the user logs in, he gets his own messages based on his ID.
If user is not logged yet, the URI is not visible (there is a authentication filter).
The problem is: if a already logged user discover this uri, he can submit a request passing another ID what will lead to a security problem because he will be able to get messages from another user (simply passing any random ID).
Can you propose any security model to prevent this security flaw ? (what I believe its more likely a cross-cutting concern).
Thanks, in advance!
Just off the top of my head, have the endpoint either (a) only return those messages visible by the logged-in user, or (b) only return messages if the logged-in user is the same as the userId in the URI. Which one depends on your business rules.
In the endpoint you can check for the user and then see if that user id matches the pathparam
finding the userid from the user name is as easy as selecting the id using the user name from a database
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;
import ... blablabla;
#GET
#Path("messages/{userid}")
public Response getMessages( #PathParam("userid") int userId, #Context SecurityContext context ) {
String username = context.getUserPrincipal().getName();
int id = getIdFromName(username); // define this yourself
if(userId==id) {
// output the message list
List<Message> msgs = getDemMessagesGURL(); // define this yourself
return Response.ok(new GenericEntity<List<T>>(msgs) {}).build();
} else {
// output Forbidden(403)
return Response.status(403).build();
}
}
and with oauth you can use a servlet filter to set the user principal based on the oauth signiture

Sitecore non administrator user show hidden items

I have created some Sitecore users who are not administrators and assigned them few roles. When these users access the Sitecore portal as default they are not shown hidden items and they have to go to view tab and configure it manually. Is there a way I can configure these users to view hidden items by default by doing some configurations to a user role shared between these users.
This information is retrieved by Sitecore.Shell.UserOptions.View.ShowHiddenItems property which gets this data from UserProfile (or from RegistryCache if the profile was already loaded).
User profile information is stored for every user separately and saved in database in binary column. There is no way of getting this option from user role.
Still you can write a script that will loop through all users in the role you mentioned and set the value in profile of those users:
public static void SetHiddenItemsValue(User user)
{
string key = "/Current_User/UserOptions.View.ShowHiddenItems";
string value = "true";
if (!(user != null))
return;
key = StringUtil.Left(key, 250);
key = key.Replace("Current_User", user.Name);
user.Profile[key] = value;
user.Profile.Save();
RegistryCache registryCache = CacheManager.GetRegistryCache(Sitecore.Context.Site);
if (registryCache == null)
return;
registryCache.Clear();
}
An alternative option from Maras is you could possibly hook into the security:loggedin event and set that value.
Your class needs to inherit from Sitecore.Pipelines.LoggedIn.LoggedInProcessor
That'll need to do something like the following:
public override void Process(LoggedInArgs args)
{
var user = Sitecore.Security.Accounts.User.FromName(args.Username, true);
var key = "/" + args.Username + "/UserOptions.View.ShowHiddenItems";
// if user needs to be in a specific role only, check that here
// if (user.IsInRole("yourrolename"))
if (String.IsNullOrEmpty(user.Profile[key]))
{
user.Profile[key] = "true";
user.Profile.Save();
}
}