I have some problems with ADFS authentication with c#. I got an application that should authenticate under some user profile on ShaprePoint On-Premises site. This site has ADFS authentication. I found some examples, but every time I got an error. And I don't know why. I am using OfficeDevPnP AuthenticationManager classes.
Here is code.
string webUrl = #"https://site.domain.com/";
string userName = "UserName";
string password = "password";
string domain = "site.domain.com";
string sts = "adfs.domain.com";
string idpld = clientIdpl;
OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager();
using (var ctx = am.GetADFSUserNameMixedAuthenticatedContext(webUrl, userName, password, domain, sts, idpld))
{
//Trying to load web element
Web web = ctx.Web;
ctx.Load(web, w => w.Title, w => w.ServerRelativeUrl, w => w.AlternateCssUrl);
ctx.ExecuteQueryRetry();
}
An error: Invalid URI: The format of the URI could not be determined.
Related
I am creating a simple console application that connect to SharePoint Server 2016. However, I receiver error 401 unauthorized when it gets to context.ExecuteQuery. I have no issues connecting to SharePoint Online. The issue is perculiar to SharePoint Onpremise. Below is my code
string siteUrl = "http://abc.mysharepoint.local/sites/mysite";
string userName = "myname#domain.com";
string pwd = "mypassword";
string domain = "domain.com";
using (ClientContext ctx = new ClientContext(siteUrl))
{
try
{
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
ctx.Credentials = new System.Net.NetworkCredential(userName, pwd, domain);
ctx.Load(ctx.Web, w => w.Title, w => w.Description);
ctx.ExecuteQuery();
Console.WriteLine(ctx.Web.Title);
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message} ");
}
}
Please what could be the possible cause and how to resolve it. I have full admin right to the site and can access the site from the browser. I have the IP to the server configured on my computer host file.
I have checked the SharePoint Server and can confirm I have access and everything looks okay. I also tried with the credentials of a service account but am still getting same 401 unauthorized error though I have full admin access to the site.
I have signed up for the Office 365 Developer Edition with Microsoft 365 E5 Developer (without Windows and Audio Conferencing). I am writing codes to connect to the Sharepoint of developer domain. Following are my codes:
public static String GetList( ICredentials credentials)
{
var authManager = new OfficeDevPnP.Core.AuthenticationManager();
using (ClientContext clientContext =
authManager.GetWebLoginClientContext("https://xxx.sharepoint.com"))
{
clientContext.Credentials = credentials;
Web web = clientContext.Web;
clientContext.Load(web,
webSite => webSite.Title);
clientContext.ExecuteQuery();
return web.Title;
}
}
public string callSharepoint()
{
const string userName = "Username#domain.onmicrosoft.com";
const string password = "xxxx";
var securePassword = new SecureString();
foreach (var c in password)
{
securePassword.AppendChar(c);
}
var credentials = new SharePointOnlineCredentials(userName, securePassword);
var list = GetList(credentials);
return list.ToString();
}
While running, it first asks to enter Microsoft Office credentials, and then it does verification by sending code to contact number and then after verification is completed it throws an Exception on Line
clientContext.ExecuteQuery(). The Exception is as follow:
Microsoft.SharePoint.Client.IdcrlException: 'The sign-in name or password does not match one in the Microsoft account system.'
The credentials I am using is of Admin Account with role Global Administrator. I also tried to add new user account in that Active Directory and tried that credentials but still got the same exception on the same place.
I even try to remove Pnp Authorization, Enable and disable Multi factor Authorization, but no success. However, I can successfully log in into the Sharepoint site on browser by using exactly same credentials.
What I think is, there is most likely a problem in the setup which I did while setting office account developer subscription. And maybe nothing is wrong with the code because I used the same codes to log in to my organization's Sharepoint and it works perfectly fine. Maybe I need something else to be configured in my developer's Office Account.
Please let me know if anyone already has some knowledge about this problem.
You have init the credential so you could use it directly, if issue exists, should be related to your user account or license.
public static String GetList(ICredentials credentials)
{
//var authManager = new OfficeDevPnP.Core.AuthenticationManager();
//using (ClientContext clientContext =
//authManager.GetWebLoginClientContext("https://xxx.sharepoint.com/sites/lee"))
//{
//}
using (ClientContext clientContext = new ClientContext("https://xxx.sharepoint.com/sites/lee"))
{
clientContext.Credentials = credentials;
Web web = clientContext.Web;
clientContext.Load(web,
webSite => webSite.Title);
clientContext.ExecuteQuery();
return web.Title;
}
}
public string callSharepoint()
{
const string userName = "user#xxx.onmicrosoft.com";
const string password = "password";
var securePassword = new SecureString();
foreach (var c in password)
{
securePassword.AppendChar(c);
}
var credentials = new SharePointOnlineCredentials(userName, securePassword);
var list = GetList(credentials);
return list.ToString();
}
Ok I found the solution.
That is I don't need this line of code:
clientContext.Credentials = credentials;
Since MFA is enabled, so when I logged in via Pnp Authenticator, it should use that user account. Instead of the one which is passed via SharePointOnlineCredentials.
I want to provide a user name and password to a .Net Console app or Web Page, to authenticate against Active Directory Federation Services.
At this point all I have is https://mycompany.com/FederationMetadata/2007-06/FederationMetadata.xml, and I have valid user name and password to test.
I followed some articles, viz., https://dotnetcodr.com/2013/02/28/claims-based-authentication-in-mvc4-with-net4-5-c-part-2-storing-authentication-data-in-an-authentication-session/
I reviewed and found that, we have to add "Rely Party" in ADFS, to use ADFS as auth store.
In 2nd Link, it is using Federated IdP. Instead I want to use some console appto provide username and password and get authenticated.
But it is not clear for me that, where to provide user name and password, in console app.
Any help is appreciated! Thanks in advance.
Following code works for me
using System.IdentityModel.Tokens;
using Microsoft.IdentityModel.Protocols.WSTrust;
using System.ServiceModel;
using System.ServiceModel.Security;
using WSTrustChannel = Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel;
using WSTrustChannelFactory = Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory;
namespace SOS.Tools.AdfsConnectionChecker
{
internal class Token
{
public static SecurityToken GetToken(string username, string password, string tokenIssuer, string appliesTo, out RequestSecurityTokenResponse rsts)
{
WS2007HttpBinding binding = new WS2007HttpBinding();
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
var tokenIssuerUrlFormat = "https://{0}/adfs/services/trust/13/usernamemixed";
var tokenIssuerUrl = string.Format(tokenIssuerUrlFormat, tokenIssuer);
WSTrustChannelFactory trustChannelFactory =
new WSTrustChannelFactory(binding, new EndpointAddress(tokenIssuerUrl));
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
trustChannelFactory.Credentials.UserName.UserName = username;
trustChannelFactory.Credentials.UserName.Password = password;
trustChannelFactory.ConfigureChannelFactory();
// Create issuance issuance and get security token
RequestSecurityToken requestToken = new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue);
requestToken.AppliesTo = new EndpointAddress(appliesTo);
WSTrustChannel tokenClient = (WSTrustChannel) trustChannelFactory.CreateChannel();
SecurityToken token = tokenClient.Issue(requestToken, out rsts);
return token;
}
}
username - Domain user name (e.g Name.FamalyName#DomainName.local)
password - Domain user password
tokenIssuer - ADFS URL (adfs.somedomain.com). That ADFS should be connected to Active Directory where username is created
appliesTo - Applicattion you want token for (e.g. https://apps.anydomain.com/WcfService1). It has to be configured on the tokenIssuer as Rellying Party.
Objective:
I am trying to build Proof Of Concept client app to implement Single Sign On by using SSPI. I am new to C# and I am getting confused.
What I know and have done so far:
All users are part of Active Directory domain, so I know Kerberos is being used for authentication during login. All I need to do at this point is to get service token from Kerberos so I can pass it to the service resource instead of username and password (correct me if I am wrong). I have been provided Service Principle Name (SPN) and password that has been registered with Kerberos for the service.
I was hoping not to use Platform Invocation Services to call SSPI functions, but I will if I have to. I read through ".NET Remoting Authentication and Authorization Sample - Part I" and used Microsoft.Samples.Security.SSPI for testing. I also tried using C#/.Net Interface To The Win32 SSPI Authentication API.
So far, I can get user/client credentials, build client security context. But how do I request a Service Ticket for a given SPN?
I would appreciate your help and guidance. Please be specific if you can and let me know if you have any questions.
You can use below to get the token by giving the SPN
public String getToken(string userName)
{
using (var domainContext = new PrincipalContext(ContextType.Domain, "domain"))
{
using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
{
Console.WriteLine("User Principale name" + UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName);
string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName;
KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, new System.Net.NetworkCredential(userName, "password", "domain"));
KerberosRequestorSecurityToken T1 = k1.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
string sret = Convert.ToBase64String(T1.GetRequest());
Console.WriteLine("=====sret========" + sret);
return sret;
}
}
}
Code provided by Hasanthi worked perfectly for my need and I didn't have to use SSPI. I was asking wrong questions but I learned a lot about Kerberos and SSPI. Here is my code in a nutshell:
AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
var domain = Domain.GetCurrentDomain().ToString();
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, serviceName).UserPrincipalName;
KerberosSecurityTokenProvider tokenProvider = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, CredentialCache.DefaultNetworkCredentials);
KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
string serviceToken = Convert.ToBase64String(securityToken.GetRequest());
}
I have a client who is implementing customer portals in Sharepoint 2013 Online. The current program distributes documents to the customers by mail. Now we have to upload the documents to the customer portal.
I try to use the copy webservice in sharepoint. I created a test project and added the webservice as Web Reference and wrote the following testcode:
static void Main(string[] args)
{
string baseUrl = "https://mycustomer.sharepoint.com/sites/";
string customer = "customerportalname";
string serviceUrl = "/_vti_bin/copy.asmx";
string destinationDirectory = "/folder/";
string fileName = "uploaded.xml";
string username = "username#outlook.com";
string password = "password";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml("<fiets><onderdeel>voorwiel</onderdeel><onderdeel>achterwiel</onderdeel><onderdeel>trappers</onderdeel><onderdeel>stuur</onderdeel><onderdeel>frame</onderdeel></fiets>");
byte[] xmlByteArray;
using (MemoryStream memoryStream = new MemoryStream())
{
xmlDocument.Save(memoryStream);
xmlByteArray = memoryStream.ToArray();
}
string destinationUrl = string.Format("{0}{1}{2}{3}", baseUrl, customer, destinationDirectory, fileName);
string[] destinationUrlArray = new string[] { destinationUrl };
FieldInformation fieldInfo = new FieldInformation();
FieldInformation[] fields = { fieldInfo };
CopyResult[] resultsArray;
using (Copy copyService = new Copy())
{
copyService.PreAuthenticate = true;
copyService.Credentials = new NetworkCredential(username, password);
copyService.Url = string.Format("{0}{1}", baseUrl, serviceUrl);
copyService.Timeout = 600000;
uint documentId = copyService.CopyIntoItems(destinationUrl , destinationUrlArray, fields, xmlByteArray, out resultsArray);
}
}
When I execute the code I recieve the following error:
The request failed with the error message:
--
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
--
It looks like I'm not authenticated and get redirected. The credentials however are correct.
Does anyone have an idea? Thanks in advance!
UPDATE
To be able to connect to SharePoint 2013 Online you have to attach the Office 365 authentication cookies as explained in this post.
My problem however is that there is also an ADFS involved. How can I autheticate against the ADFS?
This error most probably occurs due to incorrect authentication mode.
Since SharePoint Online (SPO) uses claims-based authentication, NetworkCredential Class can not be utilized for authentication in SPO.
In order to perform the authentication against the ADFS in SPO you could utilize SharePointOnlineCredentials class from SharePoint Online Client Components SDK.
How to authenticate SharePoint Web Services in SharePoint Online (SPO)
The following example demonstrates how to retrieve authentication cookies:
private static CookieContainer GetAuthCookies(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var c in password) { securePassword.AppendChar(c); }
var credentials = new SharePointOnlineCredentials(userName, securePassword);
var authCookie = credentials.GetAuthenticationCookie(webUri);
var cookieContainer = new CookieContainer();
cookieContainer.SetCookies(webUri, authCookie);
return cookieContainer;
}
Example
string sourceUrl = "https://contoso.sharepoint.com/Documents/SharePoint User Guide.docx";
string destinationUrl = "https://contoso.sharepoint.com/Documents/SharePoint User Guide 2013.docx";
FieldInformation[] fieldInfos;
CopyResult[] result;
byte[] fileContent;
using(var proxyCopy = new Copy())
{
proxyCopy.Url = webUri + "/_vti_bin/Copy.asmx";
proxyCopy.CookieContainer = GetAuthCookies(webUri, userName, password);
proxyCopy.GetItem(sourceUrl,out fieldInfos,out fileContent);
proxyCopy.CopyIntoItems(sourceUrl,new []{ destinationUrl}, fieldInfos, fileContent, out result);
}
References
Remote Authentication in SharePoint Online Using Claims-Based
Authentication
SharePoint Online Client Components SDK
In my case (on premise) i have that error. when i changed at iis SharePoint authentication for web application , and disable "Forms Authentication". Now, i canĀ“t enter to SharePoint by UI, but the Web Service works... So I have revert and I have been looking and...
[Paul stork] The Web Application for this site is running in Classic Mode rather than Claims mode. This can happen if you create the web app using Powershell or upgrade from 2010. You can use PowerShell to change it.
http://technet.microsoft.com/en-us/library/gg251985.aspx
I have tried the Web Service in another new application created by UI in Central Administration (in same farm) and it had worked. The problem was the web application.
To try:
http://sharepointyankee.com/2011/01/04/the-request-failed-with-the-error-message-object-moved-sharepoint-2010-web-services-fba/
Extend your mixed authentication web application, and create a zone just for Windows Authentication, then change the Web Reference URL in the properties of your web service, to use that extended URL and port. You should have no issues of this kind anymore.