Today I tried to login on a page containing an auth form.
I'm using RestSharp on Windows Phone 7 and I tried almost everything but it didn't work.
In a browser on my desktop computer, when I use the login page (http://myanimelist.net/login.php) and enter my valid credentials, I'll be redirected to the panel page (http://myanimelist.net/panel.php)
On Windows Phone 7 (and 8) when I try to use RestSharp to auth myself, I'm redirected to the panel page but with the following error :
Error: You must first login to see this page.
In fact I'm not authenticated and I don't have the right to see the panel page.
I tried the same thing in a WPF application and there it worked.
In my WPF app I've the following code:
var client = new RestSharp.RestClient();
client.BaseUrl = "http://myanimelist.net/login.php";
client.Authenticator = new SimpleAuthenticator("username", "mylogin", "password", "mypassword");
client.CookieContainer = new CookieContainer();
var request = new RestRequest(Method.POST);
var response = client.Execute(request);
The property "response.Content" will contain the page with some informations and a Welcome message with my login. It means that I'm authenticated.
But...
With the following code in Windows Phone 7, the property "response.Content" will contain a page with some informations and the following message in it:
Error: You must first login to see this page
And here is the WP7 code used:
var client = new RestSharp.RestClient();
client.BaseUrl = "http://myanimelist.net/login.php";
client.Authenticator = new SimpleAuthenticator("username", "mylogin", "password", "mypassword");
client.CookieContainer = new CookieContainer();
var myRequest = new RestRequest(Method.POST);
client.ExecuteAsync(myRequest, response =>
{
var t = response.Content;
});
Did I miss something? Is there a difference between RestSharp on WP7 and a WPF app?
I used Fiddler to check what happens and I can see that the cookie is never set on WP7 (in the WPF app the cookie is set).
Edit:
I found something interesting, when I get the response, I can see in Fiddler that a cookie is set in the WPF app and in the WP7 app.
So I tried to add the cookie in my WP7 app before to make my request and it worked.
I added the value I could see in Fiddler but I can't find a way to retrieve these values with RestSharp.
Here is what I tried to add before to execute my request:
myRequest.AddParameter("A", "theFirstValue", ParameterType.Cookie);
myRequest.AddParameter("B", "theSecondValue", ParameterType.Cookie);
In fact I found a way to do it.
In the response I've the cookie in the Header (Set-cookie). I extract the cookie from the header and add it to my next request which requires the cookie.
Related
I'm following this guide to setup authenticating with social logins using MSAL and Web Authenticator. The example call looks like this:
WebAuthenticatorResult authResult = await WebAuthenticator.Default.AuthenticateAsync(
new Uri("https://example.com/mobileauth/Microsoft"),
new Uri("myapp://"));
But what should the second URI parameter be? In the guide it says:
The URI the flow is expected to ultimately call back to, that is registered to your app.
So how do I register a URI like that to my app?? I've tried following this guide and have 'registered' my app in azure active directory but facebook/google etc won't accept urls of the form "myapp://" as valid redirect URIs... What am I missing?
Update
So the first half of the flow is working but I keep getting errors from the OAuth providers (the green highlight in the diagram isn't working).
This from Google:
And this from Facebook:
But I've added all these valid callback URLs:
I'm afraid that example is broken.
The second URI parameter represents where your app is listening to get the authentication result.
Actually, myapp:// is not a valid URI. You should try with something like myapp://callback.
Finally got to the bottom of it thanks to this old Xamarin issue: https://github.com/xamarin/Essentials/issues/1224#issuecomment-618192336
You have to set the "CallbackPath" property in the API config like so:
.AddGoogle(g => {
g.ClientId = "{Client ID}";
g.ClientSecret = "{Client Secret}";
g.CallbackPath = "/mobileauth"; //mobileauth is api controller
g.SaveTokens = true; })
And then tell the provider of that redirect e.g. adding "https://{API-URL}/mobileauth" in google console.
Goal
I am trying to load Sharepoint site pages in Xamarin WebView with URL like SharePoint Android/iOS app showing sitepages without asking user to log in at webview.
Progress
The app uses ADAL's AcquireTokenAsync() to get the access token from Azure AD and set the WebView source as SharePoint modern site pages URL. As the user first-time signs in to the app with AcquireTokenAsync(), the webview is load site page successfully.
Issue:
After the user closes and relaunches the app, it uses AcquireTokenSilentAsync() to authenticate. But when the webview loading the site page with URL, Microsoft ask the user to log in again at webview.
Notes
After authentication with AcquireTokenSilentAsync(), there are some cookies missing in CookieManager and NSHttpCookieStorage.
I also tried with MSAL and the issue still persist.
Question
Why there are cookies missing when the app using AcquireTokenSilentAsync(). How can achieve the goal without asking user to log in twice?
Here is some snapshot of code for authentication and webview.
var platformParams = new PlatformParameters((Activity)Forms.Context);
try
{
authResult = await authContext.AcquireTokenSilentAsync(resource, clientId);
}
catch (Exception)
{
authResult = await authContext.AcquireTokenAsync(resource, clientId, uri, platformParams);
}
var sitePageWebView = new WebView
{
Source = "https://company.sharepoint.com/SitePages/page-title.aspx",
MinimumHeightRequest = 1000,
HorizontalOptions = LayoutOptions.FillAndExpand
};
We are building an electron application using v.4.1.4. Trying to access the browser window's webContents session cookies, but I am getting an empty object or undefined. The browser window is loading our web app's url and in this use case the user has logged in which sets a cookie (to our url). I can inspect the browser window and can see the cookies that exist, so I'm trying to understand why the following code isn't working:
let win = new BrowserWindow({ dimensions });
win.loadURL(ourUrl);
const ses = win.webContents.session;
console.log(win.webContents.session.cookies); <--- empty
I thought I could get the webContents session cookies, but perhaps I have to set a cookie when the user logs in.
The cookies.get API isn't very intuitive, try:
webContents.session.cookies.get({}, (err, cookies) => console.log(cookies))
I am developing app using Xamarin Forms. I have created a directory on azure portal. As i see references over internet , active directory authentication uses Microsofts login page to log in.
I want to create native login form and pass user name to active directory and authenticate it.
Is it possible to pass user credentials programatically and authenticate user?
How can i pass user credentials?
I have tried following but i got "(411) Length required" exception
var request = WebRequest.Create(string.Format(#"https://login.microsoftonline.com/{0}/oauth2/token?client_id=5e811f4f-4fa4-451e-a439-ca05cabc02d7&grant_type=password&username=02atul.com#gmail.com&password=userpassword&scope=openid", tenant));
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Debug.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
if (string.IsNullOrWhiteSpace(content))
{
Debug.WriteLine("Response contained empty body...");
}
else {
Debug.WriteLine("Response Body: \r\n {0}", content);
}
}
}
My username is my email id. Is it correct user name? As i am getting bad request error now. What's missing?
Technically you could use username and password flow which is described in more detail here with ADAL.
However, you need to revisit your scenario and understand if it really accomplishes what the Azure Active Directory Platform is for.
Users use OAuth2 based authentication to get the security and safety of only having to share their passwords with trusted identity providers like MS, FB, Google, etc... In general, the safety conscious person will NOT want to type in a password into your random website, and trust that you do not abuse that information. If you want to use AAD, you should also use our login experiences, as this is really what the customer is paying for in our service in many regards.
EDIT: If ADAL no longer supports this flow, you can simply generate the http requests yourself:
POST: https://login.microsoftonline.com/xxxxx.onmicrosoft.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
resource={resource}&client_id={clientId}&grant_type=password&username={userName}&password={password}&scope=openid&client_secret={clientSecret}
How can I create a login page using Xamarin.Forms?
I'm debugging on Android device and
on the page I try to query the given username and password from an MSSQL database in MSSQL
and if the login be successful, the page will navigate to a new page, else will show authentication failed.
How can I do this in Xamarin.Forms?
(Xamarin LoginFlow Example linked at bottom of answer)
You would have multiple Xamarin.Forms pages and use a NavigationPage to push or pop them from the (lifecycle) stack.
Ref: https://developer.xamarin.com/api/type/Xamarin.Forms.NavigationPage/
Think of each Page a complete self-contained mini application. So the Login page might handle the getting the UserID/Password interactively from the user, performing a authorization check via a server via a Rest api that performs your SQL query. If login is successful it pushes a new Forms-based page on the NavigationPage stack. i.e.
SplashScreen -> LoginPage -> MainPagePage
LoginFlow Xamarin example
This sample demonstrates how to manipulate the navigation stack in order to only display the main page of the application once the user has successfully logged in.
For more information about the sample see Hierarchical Navigation.
What you need is the following functionalities:
Web APIs (Web Service for Login - Hosted on internet or local network - Connected with your MSSql Server)
A Login Screen in Xamarin.Forms Application (You can design it on your own or use the above mentioned demo)
On Login Screen's 'Login' button click, you need to call the Login Web Service from Xamarin.Forms application.
This requires networking (Internet Permission on Android Project, through Manifest.xml). You can use Microsoft.Net.Http for Web Service Calls.
(Look at this example http://www.c-sharpcorner.com/UploadFile/nirmal.hota/consuming-restful-web-service-in-xamarin-forms-project-using/ )
If your server responses with JSON and you need to parse JSON then you can use Json.Net (Newtonsoft.Json).
Note: What I am trying to tell you is that you need to use Web Services that are connected to the database and hosted on a server. From Xamarin.Forms application, you have to call this web-service with appropriate parameters. This requires networking, so you can use Microsoft.Net.Http (or there are other plugins also available). To get response from the Web Service, if it is in Json then you can use Newtonsoft.Json to parse Json.
There is a full example of an app with login page: xamarin-forms-samples/LoginDemo/ provided by Xamarin.
So lets say you have a LoginController on asp.net web api (if you don't know how to create an asp.net web api project etc. this is not the place to learn it:) )
[RoutePrefix("v1/login")]
public class LoginController : ApiController
{
[Route("")]
[HttpPost] //I'm using post!!!!!! you may use get etc.
public IHttpActionResult Login(UserLoginData request)
{
var userData = CheckFromDb(request);
return Json(userData);
}
}
It checks your request from db (UserLoginData is a simple class lets say holds username and password), than if user exists you return another class (lets say it is UserData hat holds name,surname, birthday etc.). If it can not find login it may return null. It's up to you.
So it will be available on your host machine like
localhost:34252/v1/login
(34252 your port-may change for you)
So you have to call it from the device (xamarin.forms) code like this
public string Post(string url, UserLoginData userLoginData)
{
//url is login url as defined above and userLoginData holds your
//user interface (textbox) data :)
using (var client = new HttpClient())
{
client.Timeout = new TimeSpan(0, 0, 30);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content;
content = new StringContent(JsonConvert.SerializeObject(userLoginData), Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync(url, content).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception("call failed");
}
//this is your response as json
var responseString = response.Content.ReadAsStringAsync().Result;
//you can convert it and check to a specific class if you need
var userData = JsonConvert.DeserializeObject<UserData>(responseString);
}
}
So UserLoginData and UserData classes both must exists on both sides. You can use Newtonsoft.Json library for json parsing (jsonconvert is it's method). Hope this helps you
And android device simulator networking is a bit tricky. You may not connect to localhost directy. It may take an address like 10.0.2.* for androidemulator or 10.71.34.* for xamarin simulator. Please check your network cards for ip addresses and findthe correct one via "cmd.exe" and "ipconfig /all" command.