I have a website where a user can authenticate with their facebook account or twitter:
to know the user I used the cookie:
Global.asax:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
var id = new MyIdentity(authTicket);
var userData = authTicket.UserData.Split(',');
id.SocialProviderName = userData[0].Replace("providerslist=", "").Split('|')[0];
var newUser = new MyPrincipal(id);
Context.User = newUser;
}
}
the user can link two accounts (facebook and twitter). connect with
twitter and then click on "account linking" and will be redirect to authenticate with her facebook account
the problem is that when redirecting to the second account the cookie becomes null and
if (this.HttpContext.Request.IsAuthenticated)
{...}
return false
(if I connect with a single account the cookie is valid no problem)
My Controller:
....
FormsAuthentication.SetAuthCookie(socialProfile.UserId, true);
ResetFormsCookie(providerName, socialProfile.UserId);
....
UserId generate by GUID
public void ResetFormsCookie(string providerName, string userId)
{
var authCookie = HttpContext.Current.ApplicationInstance.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null)
{
authCookie = FormsAuthentication.GetAuthCookie(userId, true);
}
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
var userData = authTicket.UserData;
var providerslist = (from c in userData.Split(',') where c.Contains("providerslist=") select c).FirstOrDefault();
if (string.IsNullOrEmpty(providerslist))
{
userData += string.IsNullOrEmpty(userData) ? "providerslist=" + providerName : ",providerslist=" + providerName;
}
else
{
if (!providerslist.Contains(providerName))
{
userData = userData.Replace(providerslist, providerslist + "|" + providerName);
}
}
var newTicket = new FormsAuthenticationTicket(authTicket.Version, authTicket.Name, authTicket.IssueDate
, DateTime.Now.AddDays(90) // authTicket.Expiration ToDo: This need to set in the config
, authTicket.IsPersistent, userData);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
HttpContext.Current.Response.Cookies.Add(authCookie);
}
I apologize for my English
Thanks,
Related
Why I get this error message when trying to use the Xamarin.Auth Api?
I am running on Android Plataform and using Xamarin.Forms
OAuth2Authenticator auth = new OAuth2Authenticator
(
clientId: AppKeyDropboxtoken,
scope: "",
authorizeUrl: new Uri("https://www.dropbox.com/oauth2/authorize"),
redirectUrl: new Uri(RedirectUri),
isUsingNativeUI: false
);
auth.Completed += (sender, eventArgs) =>
{
if (eventArgs.IsAuthenticated)
{
// Use eventArgs.Account to do wonderful things
this.AccessToken = eventArgs.Account.Properties["access_token"].ToString();
Debug.WriteLine("AccessToken: " + this.AccessToken);
openDropboxFileList();
}
};
var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
presenter.Login(auth);
Create a class and add this code below:
public class AuthenticatorExtensions : OAuth2Authenticator
{
public AuthenticatorExtensions(string clientId, string clientSecret, string scope, Uri authorizeUrl, Uri redirectUrl, Uri accessTokenUrl, GetUsernameAsyncFunc getUsernameAsync = null, bool isUsingNativeUI = false) : base(clientId, clientSecret, scope, authorizeUrl, redirectUrl, accessTokenUrl, getUsernameAsync, isUsingNativeUI)
{
}
protected override void OnPageEncountered(Uri url, System.Collections.Generic.IDictionary<string, string> query, System.Collections.Generic.IDictionary<string, string> fragment)
{
// Remove state from dictionaries.
// We are ignoring request state forgery status
// as we're hitting an ASP.NET service which forwards
// to a third-party OAuth service itself
if (query.ContainsKey("state"))
{
query.Remove("state");
}
if (fragment.ContainsKey("state"))
{
fragment.Remove("state");
}
base.OnPageEncountered(url, query, fragment);
}
}
Then use it as below:
[Obsolete]
private void SignInGoogleAuth()
{
try
{
string clientId = null;
string redirectUri = null;
//Xamarin.Auth.CustomTabsConfiguration.CustomTabsClosingMessage = null;
clientId = Constants.GoogleAndroidClientId;
redirectUri = Constants.GoogleAndroidRedirectUrl;
account = store.FindAccountsForService(Constants.AppName).FirstOrDefault();
var authenticator = new AuthenticatorExtensions(
clientId,
null,
Constants.GoogleScope,
new Uri(Constants.GoogleAuthorizeUrl),
new Uri(redirectUri),
new Uri(Constants.GoogleAccessTokenUrl),
null,
true);
authenticator.Completed += OnAuthCompleted;
authenticator.Error += OnAuthError;
AuthenticationState.Authenticator = authenticator;
var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
presenter.Login(authenticator);
}
catch (Exception ex)
{
ShowAlert("Alert", ex.Message);
}
}
[Obsolete]
async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
{
var authenticator = sender as OAuth2Authenticator;
if (authenticator != null)
{
authenticator.Completed -= OnAuthCompleted;
authenticator.Error -= OnAuthError;
}
if (e.IsAuthenticated)
{
// If the user is authenticated, request their basic user data from Google
// UserInfoUrl = https://www.googleapis.com/oauth2/v2/userinfo
var request = new OAuth2Request("GET", new Uri(Constants.GoogleUserInfoUrl), null, e.Account);
var response = await request.GetResponseAsync();
if (response != null)
{
// Deserialize the data and store it in the account store
// The users email address will be used to identify data in SimpleDB
string userJson = await response.GetResponseTextAsync();
StaticVariables.googleProfile = JsonConvert.DeserializeObject<GoogleProfile>(userJson);
}
if (account != null)
{
store.Delete(account, Constants.AppName);
}
await store.SaveAsync(account = e.Account, Constants.AppName);
Application.Current.Properties.Remove("Id");
Application.Current.Properties.Remove("FirstName");
Application.Current.Properties.Remove("LastName");
Application.Current.Properties.Remove("DisplayName");
Application.Current.Properties.Remove("EmailAddress");
Application.Current.Properties.Remove("ProfilePicture");
Application.Current.Properties.Add("Id", StaticVariables.googleProfile.Id);
Application.Current.Properties.Add("FirstName", StaticVariables.googleProfile.GivenName);
Application.Current.Properties.Add("LastName", StaticVariables.googleProfile.FamilyName);
Application.Current.Properties.Add("DisplayName", StaticVariables.googleProfile.Name);
Application.Current.Properties.Add("EmailAddress", StaticVariables.googleProfile.Email);
Application.Current.Properties.Add("ProfilePicture", StaticVariables.googleProfile.Picture);
await Navigation.PushAsync(new GoogleProfilePage());
}
}
[Obsolete]
void OnAuthError(object sender, AuthenticatorErrorEventArgs e)
{
var authenticator = sender as OAuth2Authenticator;
if (authenticator != null)
{
authenticator.Completed -= OnAuthCompleted;
authenticator.Error -= OnAuthError;
}
Debug.WriteLine("Authentication error: " + e.Message);
}
I was getting the infamous "Possible Forgery!" error and overrode OnPageEncountered() to work around it as many have done. This turns out to be unnecessary as well as insecure.
Oauth2Authenticator is stateful so you will get this problem if you don't use the same instance of OAuth2Authenticator to invoke OnPageLoading() as was used to initiate the authentication.
To resolve, just save the instance of OAuth2Authenticator used for initiating authentication and then reuse it when calling OnPageLoading() in your OauthInterceptor.
I am implementing a simple Forgot password, feature in my Xamarin Forms app. When the player provides an email in the text field, will check if the email exists in the database, if yes, will get the password associated with that email and send the password to that email.
In the following smtp step SmtpServer.Credentials = new System.Net.NetworkCredential("email", "password");from where do we get the credentials to provide in Network credentials as email / password ?
namespace soccerapp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ForgotPassword : ContentPage
{
private SQLiteConnection conn;
string emailText;
public ForgotPassword()
{
InitializeComponent();
conn = DependencyService.Get<Isqlite>().GetConnection();
}
public void btnSend_Clicked(object sender, EventArgs e)
{
emailText = txtEmail.Text;
int count = (from x in conn.Table<PlayerDetails>().Where(x => x.Email == emailText) select x).Count();
if (count != 0)
{
var detail = conn.Table<PlayerDetails>().First(x => x.Email == emailText);
var playerPassword = detail.Password;
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("admin#somesite.nz");
mail.To.Add(emailText);
mail.Subject = "Hello";
mail.Body = "Your soccer password: "+playerPassword;
SmtpServer.Port = 587;
SmtpServer.Host = "smtp.gmail.com";
SmtpServer.EnableSsl = true;
SmtpServer.UseDefaultCredentials = false;
SmtpServer.Credentials = new System.Net.NetworkCredential("some_email#gmail.com", "password");
SmtpServer.Send(mail);
}
catch (Exception ex)
{
DisplayAlert("Faild", ex.Message, "OK");
}
}
}
}
}
How can I check the user is exist or not in Active Directory.
we are passing emailId as userName to the method parameter and it is GET method.
We have written this method, but it is not working properly.
[HttpGet("GetADUsers")]
public List<string> GetADUsers(string userName)
{
var domainUsers = new List<string>();
try
{
string domainName = _domainSettings.Value.DomainName;
string domainUserName = _domainSettings.Value.UserName;
string domainPassword = _domainSettings.Value.Password;
PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName, domainUserName, domainPassword, ContextOptions.SimpleBind.ToString());
UserPrincipal principalUser = new UserPrincipal(pc);
using (var search = new PrincipalSearcher(principalUser))
{
foreach (var user in search.FindAll().Where(x => x.DisplayName == userName))
{
if (user.DisplayName != null)
{
domainUsers.Add(user.DisplayName);
}
}
}
}
catch (Exception ex)
{
ex.Message.ToString();
}
return domainUsers;
}
After you've created the PrincipalContext, you could just call UserPrincipal.FindByIdentity() - if the user is found, you get back the UserPrincipal - otherwise null.
[HttpGet("GetADUsers")]
public bool ADUserExists(string userName)
{
string domainName = _domainSettings.Value.DomainName;
string domainUserName = _domainSettings.Value.UserName;
string domainPassword = _domainSettings.Value.Password;
PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName, domainUserName, domainPassword, ContextOptions.SimpleBind.ToString());
UserPrincipal principalUser = UserPrincipal.FindByIdentity(pc, userName);
if (principalUser != null)
{
// gefunden ....
return true;
}
else
{
// nicht gefunden
return false;
}
}
Here I'm using Web API Authentication to check user credentials against my database. I wrote a condition in my Repo.cs file:
public bool EmailValidation(string UserName, string password)
{
var x = (from n in db.LoginCrediential
where n.UserName == UserName && n.Password == password
select n);
if (x != null)
return true;
else
return false;
}
I have a class file with name MyAuthorizationServerProvider. When I enter credentials against my db it accepts my details, but why is it not moving inside my if condition?
public class MyAuthorizationServerProvider: OAuthAuthorizationServerProvider
{
ICrendentials objcredential = new Crendentials();
LoginCrediential objUser = new LoginCrediential();
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated(); //
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (context.UserName == objUser.UserName && context.Password == objUser.Password)
{
var x = objcredential.EmailValidation(context.UserName, context.Password);
if (x==true)
{
}
}
else
{
context.SetError("invalid_grant", "Provided username and password is incorrect");
return;
}
}
}
I am trying to add Google login in my universal app,For Windows 8.1 app,it's easy to do but in case of Windows Phone 8.1 WinRT app,
Here is the code I did:
private String simpleKey = "YOUR_SIMPLE_API_KEY"; // Should keep this secret
private String clientID = "ffffff- n12s9sab94p3j3vp95sdl7hrm2lbfk3e.apps.googleusercontent.com";
private string CALLBACKuri = "writeprovidedcallbackuri";
private String clientSecret = "LYffff2Q6MbgH623i"; // Keep it secret!
private String callbackUrl = "urn:ietf:wg:oauth:2.0:oob";
private String scope = "https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email";
public GooglePlusLoginPage()
{
this.InitializeComponent();
refreshToken = null;
code = null;
access_token = null;
renderArea = this;
Auth();
}
public void Auth()
{
Windows.Storage.ApplicationData.Current.LocalSettings.Values["code"] = "";
if (access_token == null)
{
if (refreshToken == null && code == null)
{
try
{
String GoogleURL = "https://accounts.google.com/o/oauth2/auth?client_id=" + Uri.EscapeDataString(clientID) + "&redirect_uri=" + Uri.EscapeDataString(callbackUrl) + "&response_type=code&scope=" + Uri.EscapeDataString(scope);
System.Uri StartUri = new Uri(GoogleURL);
// When using the desktop flow, the success code is displayed in the html title of this end uri
System.Uri EndUri = new Uri("https://accounts.google.com/o/oauth2/approval?");
WebAuthenticationBroker.AuthenticateAndContinue(StartUri, EndUri, null, WebAuthenticationOptions.None);
// await Task.Delay(2);
}
catch (Exception Error)
{
((GooglePlusLoginPage)renderArea).SendToLangingPage();
}
}
}
//codeToAcccesTok();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string name = e.Parameter as string;
IsGplusLogin = true;
// When the navigation stack isn't restored navigate to the ScenarioList
}
private void OutputToken(String TokenUri)
{
string access_token = TokenUri;
}
public void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
{
WebAuthenticationResult result = args.WebAuthenticationResult;
if (result.ResponseStatus == WebAuthenticationStatus.Success)
{
string response = result.ResponseData.ToString();
code = response.Substring(response.IndexOf("=") + 1);
Windows.Storage.ApplicationData.Current.LocalSettings.Values["code"] = code;
// TODO: switch off button, enable writes, etc.
}
else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
{
//TODO: handle WebAuthenticationResult.ResponseErrorDetail.ToString()
}
else
{
((GooglePlusLoginPage)renderArea).SendToLangingPage();
// This could be a response status of 400 / 401
// Could be really useful to print debugging information such as "Your applicationID is probably wrong"
//TODO: handle WebAuthenticationResult.ResponseStatus.ToString()
}
codeToAcccesTok();
}
interface IWebAuthenticationContinuable
{
/// <summary>
/// This method is invoked when the web authentication broker returns
/// with the authentication result
/// </summary>
/// <param name="args">Activated event args object that contains returned authentication token</param>
void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args);
}
private async void codeToAcccesTok()
{
string oauthUrl = "https://accounts.google.com/o/oauth2/token";
HttpClient theAuthClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, oauthUrl);
// default case, we have an authentication code, want a refresh/access token
string content = "code=" + code + "&" +
"client_id=" + clientID + "&" +
"client_secret=" + clientSecret + "&" +
"redirect_uri=" + callbackUrl + "&" +
"grant_type=authorization_code";
if (refreshToken != null)
{
content = "refresh_token=" + refreshToken + "&" +
"client_id=" + clientID + "&" +
"client_secret=" + clientSecret + "&" +
"grant_type=refresh_token";
}
request.Method = HttpMethod.Post;
request.Content = new StreamContent(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(content)));
request.Content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
try
{
HttpResponseMessage response = await theAuthClient.SendAsync(request);
parseAccessToken(response);
}
catch (HttpRequestException)
{
}
}
public async void parseAccessToken(HttpResponseMessage response)
{
string content = await response.Content.ReadAsStringAsync();
//content="{\n \"error\" : \"invalid_request\",\n \"error_description\" : \"Missing required parameter: code\"\n}";
if (content != null)
{
string[] lines = content.Replace("\"", "").Replace(" ", "").Replace(",", "").Split('\n');
for (int i = 0; i < lines.Length; i++)
{
string[] paramSplit = lines[i].Split(':');
if (paramSplit[0].Equals("access_token"))
{
access_token = paramSplit[1];
}
if (paramSplit[0].Equals("refresh_token"))
{
refreshToken = paramSplit[1];
Windows.Storage.ApplicationData.Current.LocalSettings.Values["refreshToken"] = refreshToken;
}
}
//access_token="ya29.aAAvUHg-CW7c1RwAAACtigeHQm2CPFbwTG2zcJK-frpMUNqZkVRQL5q90mF_bA";
if (access_token != null)
{
getProfile();
}
else
{
((GooglePlusLoginPage)renderArea).SendToLangingPage();
// something is wrong, fix this
}
}
}
private async void ParseProfile(HttpResponseMessage response)
{
string content = await response.Content.ReadAsStringAsync();
if (content != null)
{
var serializer = new DataContractJsonSerializer(typeof(UserEmail));
UserInfo = serializer.ReadObject(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(content))) as UserEmail;
((GooglePlusLoginPage)renderArea).RenderUser();
WebView wb = new WebView();
var url = "http://accounts.google.com/Logout";
wb.Navigate(new Uri(url, UriKind.RelativeOrAbsolute));
}
}
public async void getProfile()
{
httpClient = new HttpClient();
var searchUrl = "https://www.googleapis.com/oauth2/v2/userinfo";
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + access_token);
try
{
HttpResponseMessage response = await httpClient.GetAsync(searchUrl);
ParseProfile(response);
}
catch (HttpRequestException hre)
{
// DebugPrint(hre.Message);
}
}
public async void RenderUser()
{
GridProgressRing.Visibility = Visibility.Visible;
Imageuri = UserInfo.picture.ToString().Replace("sz=50", "sz=150");
displayname = UserInfo.name;
Google_Id = UserInfo.id;
emailid = UserInfo.Email;
first_name = displayname;
uniqueName = Imageuri.ToString();
string Imagefile = "";
if (ShareMenuClass.CheckInternetConnection())
{
Imagefile = await ShareMenuClass.ToBase64String(Imageuri);
}
if (first_name.Contains(' '))
{
string[] dfdf = new string[2];
dfdf = first_name.Split(' ');
first_name = dfdf[0];
last_name = dfdf[1];
}
password = "google user";
string DataString = "<UserRegistration>" + "<FirstName>" + first_name + "</FirstName><LastName>" + last_name + "</LastName><Platform>Windows 8</Platform>" +
"<UUID>" + getDeviceId() + "</UUID><EmailId>" + emailid + "</EmailId><Password>" + password + "</Password><Photo>" + Imagefile +
"</Photo><OrganiztionName>" + organization_name + "</OrganiztionName><Location>indore</Location><AppId>2</AppId><querytype>register</querytype></UserRegistration>";
if (ShareMenuClass.CheckInternetConnection())
{
string Front = "<UserRegistration xmlns=\"www.XMLWebServiceSoapHeaderAuth.net\"> <UserRegistrationXml>";
string Back = "</UserRegistrationXml></UserRegistration>";
DataString = DataString.Replace("<", "<");
DataString = DataString.Replace(">", ">");
DataString = Front + DataString + Back;
string RecivedString = await ShareMenuClass.CallWebService("UserRegistration", DataString);
bool flagtoFillDefaultProgress = true;
if (RecivedString.Contains("Email Id is already registered"))
{
flagtoFillDefaultProgress = false;
string SoapXml = "<getuserProgressInfo><EmailId>" + emailid + "</EmailId><AppId>2</AppId></getuserProgressInfo>";
Front = "<getuserProgress xmlns=\"www.XMLWebServiceSoapHeaderAuth.net\"><getuserProgressInfoXml>";
Back = "</getuserProgressInfoXml></getuserProgress>";
SoapXml = SoapXml.Replace("<", "<");
SoapXml = SoapXml.Replace(">", ">");
SoapXml = Front + SoapXml + Back;
RecivedString = await ShareMenuClass.CallWebService("getuserProgress", SoapXml);
}
if (RecivedString.Contains("success"))
{
txtplswait.Text = "Configuring your account...";
RecivedXml.RecivedStringToObserCollection(RecivedString);
//if (flagtoFillDefaultProgress)
//{
await System.Threading.Tasks.Task.Delay(25);
await RecivedXml.FillMyHalfList();
//}
RecivedXml.SerializeRecivedRecivedollection();
ShareMenuClass.Google_Loging = true;
if (RecivedXml.WholeRecivedData[0].response == "success")
{
StorageFile storagefile = await ApplicationData.Current.LocalFolder.CreateFileAsync("IsGoogleUser.txt", CreationCollisionOption.ReplaceExisting);
RecivedXml.SerializeSignedUserInfo(RecivedXml.WholeRecivedData[0].Id);
Quizstatemodleobj.GetOverallQuizProgressForAllUserAndFillThisUserList(RecivedXml.WholeRecivedData[0].Id);
await System.Threading.Tasks.Task.Delay(25);
GridProgressRing.Visibility = Visibility.Collapsed;
Frame.Navigate(typeof(TrainingModulesPage));
}
}
else
{
MessageDialog msg1 = new MessageDialog("Somthing went wrong.Try again later!");
await msg1.ShowAsync();
Frame.Navigate(typeof(RegistrationPage));
}
}
else
{
MessageDialog msg1 = new MessageDialog("You are not connected to internet!");
await msg1.ShowAsync();
Frame.Navigate(typeof(RegistrationPage));
}
}
public Page renderArea { get; set; }
public string refreshToken { get; set; }
public string code { get; set; }
Here in ContinueWebAuthentication which is triggered after user accepts to let the app get the profile info the value of "code" is not the desired one,In W8.1 app the value of "code" is correct but here it is not.
Due to this I am unable to get the user profile info
I finally figured this out.
Change the "redirect_uri" query parameter in the "StartUri" parameter of the AuthenticateAndContinue method to http://localhost
Change the CallbackURL (or "EndUri") parameter of the "AuthenticateAndContinue" method to also equal http://localhost
After many hours this is what worked for me. I found the answer by browsing the code at: http://code.msdn.microsoft.com/windowsapps/Authentication-using-bb28840e and specifically looking at the class "GoogleService.cs" in the Authentication.Shared project of the solution.
Hope this helps.