Get membership provider Name - sharepoint

I am using Asp.net memebership provider for FBA in sharePoint 2013. Please let me know how to dynamically find membership provider name.
Thanks in advance.

Thanks for the response.
My scenario is I am dynamically planning to get membership provider as I have to create token during forms authentication.
I found the answer
private static string GetFbaZoneUrl(SPWeb web)
{
string providerAndRole = null;
SPWebApplication webApp = web.Site.WebApplication;
foreach (var zone in webApp.IisSettings.Keys)
{
var settings = webApp.IisSettings[zone];
var fbaProvider = webApp.IisSettings[zone].FormsClaimsAuthenticationProvider;
if (fbaProvider != null)
{
// We found the zone on the web app where FBA is enabled.
// This is the zone whose URL we want.
// SPAlternateUrl fbaUrl = webApp.AlternateUrls.GetResponseUrl(zone, false);
providerAndRole = fbaProvider.MembershipProvider + "," + fbaProvider.RoleProvider;
break;
}
}
return providerAndRole;
}
Hope this code helps someone.
Thanks
Rama

This is quite easy , in CSOM get the current username (if you are logged in with a forms based account) .The username will be of the following format :
"i:0#.f|membership|someone.example.com"
The "i:0#.f|membership|someone.example.com" is the membership provider name. Use javascript substring function to get this section.
To get the current user loginname, use the following code which is also provided here
function GetCurrentUsername()
{
var ctxt = new SP.ClientContext.get_current();
this.website = ctxt.get_web();
this.currentUser = website.get_currentUser();
ctxt.load(currentUser);
ctxt.executeQueryAsync(Function.createDelegate(this, this.onSucceess), Function.createDelegate(this, this.onFail));
}
function onSucceess(sender, args)
{
alert(currentUser.get_loginName());
}
function onFail(sender, args)
{
alert('request failed ' + args.get_message() + '\n'+ args.get_stackTrace());
}

Related

Programmatically modify ACL to give application pool all permissions to application (IIS)

I have a process that creates an application and application pool using the Server Manager object in the Microsoft.Web.Administration namespace, the application pool is created first and then the application, assigning the newly created app pool to the application, code below.
protected TResult UseServerManagerWrapper<TResult>(Func<ServerManager, TResult> func)
{
using (var serverManager = new ServerManager())
{
return func(serverManager);
}
}
Application creation function
public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
{
UseServerManagerWrapper(serverManager =>
{
var site = serverManager.Sites[siteName];
var newApplication =
site.Applications.Add(
GetApplicationPath(parentApplicationName, organisationName, applicationName),
this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName));
newApplication.ApplicationPoolName = applicationPoolName;
serverManager.CommitChanges();
return true;
});
}
and app pool creation.
public Boolean CreateApplicationPool(String applicationPoolName)
{
return UseServerManagerWrapper(serverManager =>
{
var appPool = serverManager.ApplicationPools.Add(applicationPoolName);
appPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
appPool.ManagedRuntimeVersion = "";
serverManager.CommitChanges();
return true;
});
}
This all works fine, the only problem I have is that I have to go into the application folder and manually assign permissions for the application pool.
I can't see anything in the ServerManager documentation that can help me and I can't figure out a way to use the Directory.SetAccessControl Method to give an application pool permissions. Is there anyway to do this in code?
Apologies if I'm using wrong terminology or anything, I'm new to publishing in general. Let me know if you need anymore info.
Ok, so after a lot of searching and some trial and error I've found the resolution and it's nothing to do with the ServerManager object. First of all to get this to work in ASP.NET Core 2.1 (1.x/2.x) I needed the System.IO.FileSystem.AccessControl Nuget and the Namespaces below.
using System.Security.AccessControl;
using System.Security.Principal;
These give the ability to modify the ACL of files and folders and then the CreateApplication function becomes the below.
public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
{
UseServerManagerWrapper(serverManager =>
{
var site = serverManager.Sites[siteName];
var generatedPath = this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName);
var newApplication =
site.Applications.Add(
GetApplicationPath(parentApplicationName, organisationName, applicationName),
generatedPath);
newApplication.ApplicationPoolName = applicationPoolName;
var dInfo = new DirectoryInfo(generatedPath);
var acl = dInfo.GetAccessControl();
var acct = new NTAccount($"IIS APPPOOL\\{applicationPoolName}");
acl.AddAccessRule(new FileSystemAccessRule(acct, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(acl);
serverManager.CommitChanges();
return true;
});
}
The code between "newApplication.ApplicationPoolName = applicationPoolName" and "serverManager.CommitChanges()" gets the ACL from the newly generated directory giving the ability to modify it and reassign with a new FileSystemAccessRule.

Is there a way to make a comment in TFS when adding an AD user to a TFS group?

I was wondering if I can make a comment somewhere in Team Foundation Server when I add an AD user to a TFS group or change the group of the user, for auditing purpose.
I have created a PowerShell script to record day2day changes to TFS user databases and query the AD to find out who approved this change.
Now we have a self made db.
For what it's worth - I wrote a C# method to pull the list of all members from every TFS group. Hope that helps!
EDIT: "This is posted as an answer because "xidada" was going to write a script to pull the information and since I already had the code to get the information that needed, I thought the code would be a guide to help him/her with the script"
private void btn_GetNow_Click()
{
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri("http://server/collection"));
tfs.EnsureAuthenticated();
TfsConfigurationServer srv = tfs.ConfigurationServer;
CatalogNode configurationServerNode = srv.CatalogNode;
// Query the children of the configuration server node for all of the team project collection nodes
ReadOnlyCollection<CatalogNode> tpcNodes = configurationServerNode.QueryChildren(
new Guid[] { CatalogResourceTypes.ProjectCollection },
false,
CatalogQueryOptions.None
);
Guid tpcId = new Guid(tpcNodes[0].Resource.Properties["InstanceId"]);
TfsTeamProjectCollection tpc = srv.GetTeamProjectCollection(tpcId);
// get a reference to the work item tracking service
var workItemStore = tpc.GetService<WorkItemStore>();
List<Identity> result = new List<Identity>();
// iterate over the projects
foreach (Project project in workItemStore.Projects)
{
Console.WriteLine("\tProject: {0}", project.Name);
try
{
VersionControlServer versionControl = (VersionControlServer)tpc.GetService(typeof(VersionControlServer));
TeamProject teamProject = versionControl.GetTeamProject(project.Name);
IGroupSecurityService gss = (IGroupSecurityService)tpc.GetService<IGroupSecurityService>();
Identity[] appGroups = gss.ListApplicationGroups(teamProject.ArtifactUri.AbsoluteUri);
foreach (Identity group in appGroups)
{
rtb_Users.AppendText(group.DisplayName + "\n");
Identity[] groupMembers = gss.ReadIdentities(SearchFactor.Sid, new string[] { group.Sid }, QueryMembership.Expanded);
foreach (Identity member in groupMembers)
{
if (member.Members != null)
{
foreach (string memberSid in member.Members)
{
Identity memberInfo = gss.ReadIdentity(SearchFactor.Sid, memberSid, QueryMembership.None);
if (memberInfo.Type == IdentityType.WindowsUser)
{
if (!result.Contains(memberInfo))
{
result.Add(memberInfo);
rtb_Users.AppendText("\t\t" + memberInfo.AccountName + " - " + memberInfo.DisplayName + " - " + memberInfo.Domain + "\n");
}
else
{
Console.WriteLine("\t\tUser already available " + memberInfo.AccountName);
}
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("\tThe Project: '{0}' throws an exception: {1} and will be ignored.", project.Name, ex.Message);
}
}
}
This method is pulled out from my application AS IS and would need to be customized for your needs.

Access is denied Exception when updating List items using SPUserToken

I try to do some actions on Sharepoint 2010 list using an unlowed user( having only read right) and i got Access denied exception.
Is it possible to do it whithout changing the user rights.
please find below my code:
public void StartWorkFlow(int itemID, int wfTemplateID, String entityName, String userShortname)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPUser spUser;
using (site = new SPSite(siteUrl))
{
using (web = site.RootWeb)
{
spUser = web.EnsureUser(userShortname);
}
}
using (site = new SPSite(siteUrl, spUser.UserToken))
{
using (web = site.AllWebs["WPrs"])
{
list = web.Lists["Workflow Template"];
SPListItem item = list.Items.GetItemById(wfTemplateID);
SPList processList = web.Lists["List Process " + item["Template_x0020_Name"]];
SPListItem newInstance = processList.Items.Add();
newInstance["Template_x0020_Name"] = item["Template_x0020_Name"];
newInstance["Template_x0020_Description"] = item["Template_x0020_Description"];
newInstance["Date_x0020_De_x0020_Publication"] = item["Date_x0020_De_x0020_Publication"];
newInstance["Item_x0020_Id"] = itemID;
newInstance["Item_x0020_Extradata"] = entityName.ToLower() + "||Parameter||" + "";
newInstance["CTName"] = Utility.GetInstance().GetSuperItemNameBySubItemName(entityName);
web.AllowUnsafeUpdates = true;
newInstance.Update();
web.AllowUnsafeUpdates = false;
}
}
});
}
Thank you in advance.
To be able to use site.AllWebs the user must have Full Control to the site. Instead of using AllWebs try to get the sub sites using the following code -
SPWebCollection subwebs = CurrentSite.OpenWeb().GetSubwebsForCurrentUser();
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.getsubwebsforcurrentuser%28v=office.12%29.aspx
http://social.msdn.microsoft.com/Forums/sharepoint/en-US/e7ff284f-fe4b-42fb-8b21-a475e331a18c/access-denied-for-user-with-contribute-rights?forum=sharepointdevelopmentlegacy
Also you would not be able to update a listitem with read only rights.
If the only requirement is to set up the Created By/Modified By field - you should be able to overwrite default value by using SystemUpdate instead of Update. But still you need to run this RunWithElevatedPrivileges mode instead of UserToken
Although I'm not sure what will happen if have any other dependent actions after this update (event receivers or workflows) i'm not sure what context it will use (i.e. if SharePoint internally will use current SPWeb.CurrentUser object.

Check admin privileges on cross-domain workstation C#

I am trying to check if a user is an admin on a particular machine.
I have the following code that works fine when the computer is on the same domain:
public bool CheckAdmins(string computerName)
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
string branchnumber = computerName.Substring(0, 3);
bool admin = false;
if (logonUser.authenticate())
{
using (DirectoryEntry machine = new DirectoryEntry("WinNT://" + logonUser.Domain + "/" + computerName,logonUser.Domain + "\\" + logonUser.UserID,logonUser.Password))
{
//get local admin group
using (DirectoryEntry group = machine.Children.Find("Administrators","group"))
{
//get all members of local admin group
object members = group.Invoke("Members", null);
foreach (object member in (IEnumerable)members)
{
//get account name
string accountName = new DirectoryEntry(member).Name;
bool isAdmin = principal.IsInRole(accountName);
if (isAdmin == true) { admin = true; }
}
}
}
}
return admin;
}
However, across domain, this simply comes back with 'network path not found'.
I have been experimenting with LDAP but not getting too far. I have tried a number of methods and ideally need an example. This is what I am using currently:
String strPath = "LDAP://172.24.242.51/CN=258TP520,OU=258,DC=net,DC=test,DC=co,DC=uk";
DirectoryEntry myDE = new DirectoryEntry(strPath, "testdom\user", "password");
List<string> memberof = new List<string>();
foreach (object oMember in myDE.Properties["memberOf"])
{
memberof.Add(oMember.ToString());
}
However myDE.properties doesn't seem to contain anything. All help appreciated!
Thanks
I needed to append the FQDN to the computername, like so
using (DirectoryEntry machine = new DirectoryEntry("WinNT://" + computerName + ".net.test.co.uk",logonUser.Domain + "\\" + logonUser.UserID,logonUser.Password))
This fixed my issue.

Client Object Model Sharepoint How to get the Instance ID

So In my sharepoint site contents page i have an application.
Can anyone tell me how to get the instance id of it.
so that i can invoke the link :
http://testingwebcompany.sharepoint.com/_layouts/15/appredirect.aspx?instance_id={ <>}
I can't seem to get it when I'm searching ClientContext.Web.Lists.
Thanks
I got it, it seems that the instance id is auto generated. the real url of the application is located when looping through ClientContext.Web.Webs[].Title == "Application Name" then retrieving the ClientContext.Web.Webs[].Url.
The following example demonstrates how to retrieve an App by its title
public static class WebExtensions
{
public static IEnumerable<AppInstance> GetAppInstanceByTitle(this Web web,string appTitle)
{
var ctx = web.Context;
var apps = AppCatalog.GetAppInstances(ctx, web);
var result = ctx.LoadQuery(apps.Where(a => a.Title == appTitle));
return result;
}
}
Usage
using (var ctx = new ClientContext(webUri))
{
var appTitle = "\"Napa\" Office 365 Development Tools";
var result = ctx.Web.GetAppInstanceByTitle(appTitle);
ctx.ExecuteQuery();
var app = result.FirstOrDefault();
if (app != null) Console.WriteLine(app.Id); // print App Instance Id
}

Resources