Download using WebClient - IIS Basic Authentication - c#

I am using this to download html content from a site published on IIS:
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultCredentials;
string html = client.DownloadString("http://site.com");
}
But when the IIS is set to Basic Authentication this doesn't works. The user already type user and password on the IIS dialog box.
There is a way to make this work without pass a user and password again?

I suspect that basic authentication is going to need the password, so I suspect you'll need a new System.Net.NetworkCredential("your-username","your-password"). The default credential would work with integrated auth, but not (AFAIK) basic. So in answer to:
There is a way to make this work without pass a user and password again?
No, I don't think so.

Searching more, I found this:
HttpApplication context = (HttpApplication)HttpContext.Current.ApplicationInstance;
string authHeader = context.Request.Headers["Authorization"];
string userNameAndPassword = Encoding.Default.GetString(
Convert.FromBase64String(authHeader.Substring(6)));
string[] parts = userNameAndPassword.Split(':');
Response.Write(userNameAndPassword);
We can get user and password when the IIS is set do basic authentication!

I use the following code for the NTLM authentication with default credentials
webClient.Proxy = WebRequest.GetSystemWebProxy();
webClient.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
One day I researched the problem and found this working. However, with .Net 4.0 my Visual Studio says GetSystemWebProxy is currently deprecated.

Related

Generated WCF SOAP client uses current user for windows authentication instead of given credentials

I'm kind of new to the whole WCF and SOAP topic so please be kind.
I'm using a generated SOAP Client with .net6. In another project we successfully worked with the same Web Service using the old .net Framework 2.0 Web References and the same credentials.
Strange enough everything seemed to work fine at first. Until I realized, that it does not use the given credentials to authenticate. Instead it authenticates with my own domain user.
I also tried to get it to work with explicitly setting the binding with a BasicHttpBinding but I only could get the same broken logic to work or I got various authentication/protocol/security errors.
So it seems the authentication is basically working. It just doesn't use the provided credentials. So my question is: How can I configure it to work with the provided identity?
I also found out that it might have anything to do with a cached Windows token. But how can I get rid of it. How to prevent caching in the first place?
EDIT:
Specified the variable types explicitly.
string url = "http://someServer/AdministrationService.asmx";
AdministrationServiceSoapClient client = new AdministrationServiceSoapClient(
AdministrationServiceSoapClient.EndpointConfiguration.AdministrationServiceSoap,
url);
WindowsClientCredential credential = client.ClientCredentials.Windows;
credential.ClientCredential.UserName = "username";
credential.ClientCredential.Password = "password";
credential.ClientCredential.Domain = "DOMAIN";
GetServerInfoRequest getServerInfoRequest = new GetServerInfoRequest
{
// some stuff set here
};
GetServerInfoRequest getServerInfoReply = await client.GetServerInfoAsync(getServerInfoRequest);
As far as I know, BasicHttpBinding has security disabled by default, but can be added setting the BasicHttpSecurityMode to a value other than None in the constructor. It can be configured according to the instructions in BasicHttpBinding and BasicHttpBinding Constructors.
By default, setting up client credentials involves two steps: determining the type of client credential required by the service and specifying an actual client credential, as described in this document.
After waiting a day it is working. It seems that the cached credentials became invalid somehow.
Strange enough the simple service creation from above is not working anymore. Instead I have to use the following.
var client = new AdministrationServiceSoapClient(
new BasicHttpBinding()
{
Security = new BasicHttpSecurity()
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Message = new BasicHttpMessageSecurity()
{
ClientCredentialType = BasicHttpMessageCredentialType.UserName,
},
Transport = new HttpTransportSecurity()
{
ClientCredentialType = HttpClientCredentialType.Windows,
ProxyCredentialType = HttpProxyCredentialType.Windows,
}
},
},
new EndpointAddress(url));

SSRS Forms Authentication - How To Pass Cookie Credentials To Report Server

I am currently attempting to render the SSRS report in my web application using forms authentication.
My SSRS Report Version is 2016.
Initially I was under the impression that NetworkCredentials would work, and after encountering errors, I found that we are required to use FormsAuthentication, with passing the cookie as a means of authenticating the user.
I have done the necessary settings on the config files in the Reporting Server by following the guide from the link below:-
https://github.com/Microsoft/Reporting-Services/tree/master/CustomSecuritySample2016
The reporting services works as intended on the localhost/ReportServer and on
the SSRS Portal, localhost/Reports. I am also able to access said server
remotely.
Below is the code I used to obtain the authenticated cookie.
MyReportingService rsClient = new MyReportingService();
rsClient.Url = "http://xxx.xxx.xxx.xxx/reportserver/ReportService2010.asmx";
try
{
rsClient.LogonUser("user", "password", "");
Cookie myAuthCookie = rsClient.AuthCookie;
HttpCookie cookie = new HttpCookie(myAuthCookie.Name, myAuthCookie.Value);
Response.Cookies.Add(cookie);
}
Which supposedly would then be used to authenticate the user.
Cookie authCookie = new Cookie(cookie2.Name, cookie2.Value);
authCookie.Domain = "DomainName";
rvSiteMapping.ServerReport.ReportServerCredentials = new MyReportServerCredentials(authCookie);
rvSiteMapping.ServerReport.Cookies.Add(authCookie);
And in my forms authentication within the IReportsServerCredentials Class:-
public bool GetFormsCredentials(out Cookie authCookie,
out string user, out string password, out string authority)
{
authCookie = m_authCookie;
user = password = authority = null;
return true; // Use forms credentials to authenticate.
}
The issue I am experiencing is when the application is passing the credentials to the report server. I believe I must be doing this part incorrectly because while my application does get the cookie, when it authenticates the credentials provided by the cookie, I receive the text/html error:-
Object moved to <a href="/ReportServer/logon.aspx?ReturnUrl=%2fReportserver%2fReportExecution2005.asmx" />
This error is in response to setting a default generic Identity in the event that
the HttpContext.Current.User = null.
if (HttpContext.Current != null
&& HttpContext.Current.User != null)
{
userIdentity = HttpContext.Current.User.Identity;
}
else
{
userIdentity = new GenericIdentity("AnonymousUser");
}
I have tried googling the answer but most of the results are for
windows authentication and the few that are related to forms authentication
are very similar to the code I referred to.
The underlying cause of the issue was under my nose the whole time.
The domain name should refer to the web domain and not the active directory domain.
authCookie.Domain = "DomainName";
The cookie is now able to authenticate the user as intended.
Hopefully this helps anyone who happens to make the same mistake.

OneDrive API with C#, get authentication code programmatic

I have to write an application, no matter what language (c#, Java, shell, python ...) that can connect to OneDrive and then uploads file.
Following the OneDrive API I found that i need in one step to go to the browser (manually and to post a url that combines client_id and client_security to get an authentication code so i can connect my client with it to get the access token. (oAuth2 protocol)
I need to get the access_token pragmatically, i don't need any manual step to be involved.
I tried in c# to use the WebBrowser component to navigate to the url and to get the access token, I found that the browser stays in the same url and not getting the final url that includes the auth_code!
My code looks like:
// Initialize a new Client (without an Access/Refresh tokens
var client = new Client(options);
// Get the OAuth Request Url
var authRequestUrl = client.GetAuthorizationRequestUrl(new[] { Scope.Basic, Scope.Signin, Scope.SkyDrive, Scope.SkyDriveUpdate });
// TODO: Navigate to authRequestUrl using the browser, and retrieve the Authorization Code from the response
WebBrowser wb = new WebBrowser();
wb.AllowNavigation = true;
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(authRequestUrl);
Console.WriteLine(wb.Version);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
wb.Document.InvokeScript("evt_Login_onload(event)");
Uri myUrl = wb.Url;
Anyone can help with fixing this, or maybe suggest other ideas please?
Thanks in Advance!
It looks like you're creating a Windows desktop app using C#. There's actually an example at https://msdn.microsoft.com/en-us/library/hh826529.aspx for using the WebBrowser class to get the authorization code, then the token, then make an API. In short, you'll first need to send a request to the following URL with your client_id and scopes.
https://login.live.com/oauth20_authorize.srf?client_id=YOUR_CLIENT_ID&scope=YOUR_SCOPE_STRING&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf
In the response, you'll get the authorization code which you'll need to use to send another request to with your client_id, client_secret, authorization code like the following.
https://login.live.com/oauth20_token.srf?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&redirect_uri=https://login.live.com/oauth20_desktop.srf&code=AUTHORIZATION_CODE&grant_type=authorization_code
When you finally receive the access token, you can make requests to the API using your access token similar to the following.
"https://apis.live.net/v5.0/me?access_token=ACCESS_TOKEN". The "me" can be changed to any other folder or directory.
I hope that helps.
dont u think the scope u provided are wrong, they should be wl.basic, wl.signin, and if ur using new onedrive api then it should be onedrive.readonly or onedrive.readwrite
if ur using liveconnect api for the purpose of using onedrive then scope should be wl.skydrive or wl.contacts_skydrive or wl.skydrive_update
depending upon ur uses (refer https://msdn.microsoft.com/en-us/library/hh243646.aspx)
and can u more elaborate how ur trying to get the access_token, from above it is quite confusing to me
Have you solved you issue?
Have you tried to use the LiveSDK to authenticate?
Have a look at my question there, it might help you :
Onedrive API vs LiveSDK
I have used the following code, after installing both the LiveSDK and the OneDrive SDK, and this does not require any login after the first authorization. However it "may" have to be a RT app (windows store or windows phone store)
var authClient = new LiveAuthClient();
var authResult = await authClient.LoginAsync(new string[] {
"wl.signin", "onedrive.readwrite", "onedrive.appfolder"});
if (authResult.Session == null)
throw new InvalidOperationException("You need to sign in and give consent to the app.");
var Connection = new ODConnection("https://api.onedrive.com/v1.0",
new MicrosoftAccountAuthenticationInfo() { TokenType = "Bearer",
AccessToken = odArgs.Session.AccessToken });
Toan-Nguyen's answer almost helps me. On the step 2 (when I should send a request with authorization code) I get the response with error "Public clients can't send client secret". This answer said it's neccessary to remove the attribute client_secret from url.

Linq-to-Twitter always error 401 Unauthorized

I am using LinqToTwitter in my C# desktop application. Trying to send tweets and tweets with image to Twitter using OAuth credentials. Initially I am using these required attributes of my own Twitter application:
var auth = new SingleUserAuthorizer
{
Credentials = new SingleUserInMemoryCredentials
{
ConsumerKey = "key",
ConsumerSecret = "secret",
TwitterAccessToken = "token",
TwitterAccessTokenSecret = "tokensecret"
}
};
var context = new TwitterContext(auth);
context.UpdateStatus("Hello World");
NOTE: I have double checked that I am using correct values for above keys and tokens, but its always erroring 401 Unauthorized.
NOTE: Also I have checked this link for any mistake: http://linqtotwitter.codeplex.com/wikipage?title=LINQ%20to%20Twitter%20FAQ&referringTitle=Documentation
Any help to resolve this ?
Your code seems to be fine.
The FAQ, which you reference, is the best resource right now.
What type of application are you building, e.g. ASP.NET, Windows Phone, etc.?
You might also try downloading the source code and checking to see if the LinqToTwitterDemos project will work for you.

Sharepoint connection with a username and password

i've searched during 2 days to resolve my problem but there is no way!
in fact, i'd like to connect to sharepoint using a user's account (there is no probleme when i use anonymous connexion).
i added a web reference of authentification and lists to use this code:
SPConnect.Authentication authSP = new SPConnect.Authentication();
SPLists.Lists spLists = new SPLists.Lists();
authSP.CookieContainer = new System.Net.CookieContainer();
authSP.AllowAutoRedirect = true;
SPConnect.LoginResult loginSP = authSP.Login("administrateur", "pass");
if (loginSP.ErrorCode == SPConnect.LoginErrorCode.NoError)
{
spLists.CookieContainer = authSP.CookieContainer;
//object list = spLists.GetList("presentationAccueil");
SPSite oSiteCollection = SPContext.Current.Site;
SPList listeee = oSiteCollection.AllWebs["http://vmspprod:25401"].Lists["presentationAccueil"];
}
i get this erro NotInFormsAuthenticationMode when i execute
SPConnect.LoginResult loginSP = authSP.Login("administrateur", "pass");
is there any other method to use a user's login and password?
Thank you in advance for your answers.
You need to configure your SharePoint server to use Forms Authentication (that's what the exception is telling you).
You didn't say which version of SharePoint you are targeting (WSS 3.0, SP 2007, SP 2010). Here is a link to an MSDN page that shows you how to configure your server to use Forms Authentication: http://msdn.microsoft.com/en-us/library/bb975136(v=office.12).aspx
If you cannot modify the server, then you will need to change your code to use whatever authentication mechanism the server employs.
I hope this helps.

Categories