I am currently trying to create user authentication in unity and I am having some issues.
The code below is what I have at the moment and I keep receiving the error saying Auth does not exist in the current context.
Does anyone have any idea why this is? Probably a simple fix that I am just overlooking.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Text.RegularExpressions;
using Firebase;
using Firebase.Auth;
public class Register : MonoBehaviour {
public GameObject email;
public GameObject password;
public GameObject confPassword;
private string Email;
private string Password;
private string ConfPassword;
private string form;
private bool EmailValid = false;
private string[] Characters = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9","0","_","-"};
public void RegisterButton(){
bool EM = false;
bool PW = false;
bool CPW = false;
if (Email != ""){
EmailValidation();
if (EmailValid){
if(Email.Contains("#")){
if(Email.Contains(".")){
EM = true;
} else {
Debug.LogWarning("Email is Incorrect");
}
} else {
Debug.LogWarning("Email is Incorrect");
}
} else {
Debug.LogWarning("Email is Incorrect");
}
} else {
Debug.LogWarning("Email Field Empty");
}
if (Password != ""){
if(Password.Length > 5){
PW = true;
} else {
Debug.LogWarning("Password Must Be atleast 6 Characters long");
}
} else {
Debug.LogWarning("Password Field Empty");
}
if (ConfPassword != ""){
if (ConfPassword == Password){
CPW = true;
} else {
Debug.LogWarning("Passwords Don't Match");
}
} else {
Debug.LogWarning("Confirm Password Field Empty");
}
if (EM == true&&PW == true&&CPW == true)
{
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
// Firebase user has been created.
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
}
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Tab)){
if (email.GetComponent<InputField>().isFocused){
password.GetComponent<InputField>().Select();
}
if (password.GetComponent<InputField>().isFocused){
confPassword.GetComponent<InputField>().Select();
}
}
if (Input.GetKeyDown(KeyCode.Return)){
if (Password != ""&&Email != ""&&Password != ""&&ConfPassword != ""){
RegisterButton();
}
}
Email = email.GetComponent<InputField>().text;
Password = password.GetComponent<InputField>().text;
ConfPassword = confPassword.GetComponent<InputField>().text;
}
void EmailValidation(){
bool SW = false;
bool EW = false;
for(int i = 0;i<Characters.Length;i++){
if (Email.StartsWith(Characters[i])){
SW = true;
}
}
for(int i = 0;i<Characters.Length;i++){
if (Email.EndsWith(Characters[i])){
EW = true;
}
}
if(SW == true&&EW == true){
EmailValid = true;
} else {
EmailValid = false;
}
}
}
I do not see you ever creating the variable auth?
While you refer to it here:
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
So I assume you will have to create a variable auth and instantiate it with something related to FireBase.Auth (unless I am overlooking something).
Related
Integrating facebook as an auth provider within firebase (already have a working gmail implementation). The below code works fine in Unity, the FB SDK prompts for token, enter it manually, token is passed to firebase, login can be seen in the console, the required scene is then loaded.
When this is built onto an android device the full behavior doesnt happen, the correct Facebook token is received either from fresh login or existing login, we enter the SignInWithFacebookOnFirebase function to log this account into firebase and nothing else happens, sits on the debug of ("your token is " + aToken);
Im pretty sure it has something to do with the async behaviour and maybe not awaiting the task but im not sure what, any suggestions would be great !
using System.Collections.Generic;
using UnityEngine;
using Facebook.Unity;
using TMPro;
using UnityEngine.SceneManagement;
using Firebase.Auth;
using Firebase;
public class FacebookAuth : MonoBehaviour
{
private FirebaseAuth auth;
public TMP_Text debug;
void Awake ()
{
if (FB.IsInitialized) {
FB.ActivateApp();
} else {
//Handle FB.Init
FB.Init( () => {
FB.ActivateApp();
});
}
CheckFirebaseDependencies();
}
private void CheckFirebaseDependencies()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
if (task.IsCompleted)
{
if (task.Result == DependencyStatus.Available)
auth = FirebaseAuth.DefaultInstance;
else
debug.text =("Could not resolve all Firebase dependencies: " + task.Result.ToString());
}
else
{
debug.text =("Dependency check was not completed. Error : " + task.Exception.Message);
}
});
}
void OnApplicationPause (bool pauseStatus)
{
// Check the pauseStatus to see if we are in the foreground
// or background
if (!pauseStatus) {
//app resume
if (FB.IsInitialized) {
FB.ActivateApp();
} else {
//Handle FB.Init
FB.Init( () => {
FB.ActivateApp();
});
}
}
}
private void InitCallBack()
{
if(!FB.IsInitialized)
{
FB.ActivateApp();
}
else
{
// debug.text=("Failed to initialize");
}
}
private void OnHideUnity(bool isgameshown)
{
if(!isgameshown)
{
Time.timeScale = 0;
}
else
{
Time.timeScale = 1;
}
}
public void Facebook_Login()
{
var permission = new List<string>() { "public_profile", "email" };
if (!FB.IsLoggedIn)
{
FB.LogInWithReadPermissions(permission, AuthCallBack);
}
else
{
var aToken = AccessToken.CurrentAccessToken.TokenString;
debug.text=("already logged in - starting game" + aToken);
//THIS IS THE PROBLEM ON ANDROID - ITS NOT HAPPENING/async issue?
SignInWithFacebookOnFirebase(aToken);
SceneManager.LoadScene(1);
}
}
public void LogOut()
{
FB.LogOut();
debug.text=("Logged out of facebook");
}
private void SignInWithFacebookOnFirebase(string idToken)
{
Firebase.Auth.Credential credential = Firebase.Auth.FacebookAuthProvider.GetCredential(idToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.Exception != null) {
Debug.LogWarning("SignInWithCredentialAsync encountered an error: " + task.Exception);
FirebaseException firebaseEx = task.Exception.GetBaseException() as FirebaseException;
AuthError errorCode = (AuthError)firebaseEx.ErrorCode;
string message = "Login Failed!";
switch (errorCode)
{
case AuthError.AccountExistsWithDifferentCredentials:
message = "Your account is already linked to an email address";
break;
//we can add other conditions here if required to catch exceptions
}
debug.text=(message);
}
else{
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
debug.text=("Logged into facebook");
}
});
}
private void AuthCallBack(ILoginResult result)
{
if(FB.IsLoggedIn)
{
var aToken = result.AccessToken.TokenString;
debug.text=("your token is " + aToken);
//THIS IS THE PROBLEM ON ANDROID - ITS NOT HAPPENING/async issue?
SignInWithFacebookOnFirebase(aToken);
debug.text=("weve signed into firebase");
SceneManager.LoadScene(1);
}
else
{
debug.text=("User Cancelled login");
}
}
}
EDIT - So the problem is nothing to do with async, its the fact that the firebase credential is being persisted on the mobile device. I uncommented all of my already working google auth code below and we log into firebase with our facebook creds fine! So i need some method of clearing our this token when A) the user logs out and B) the user closes the app (Cleanly or uncleanly) Any help would be great !
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Firebase;
using Firebase.Auth;
using Google;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GoogleAuth : MonoBehaviour
{ /*
public TMP_Text infoText;
public string webClientId = "<your client id here>";
private FirebaseAuth auth;
private GoogleSignInConfiguration configuration;
private void Awake()
{
configuration = new GoogleSignInConfiguration { WebClientId = webClientId, RequestEmail = true, RequestIdToken = true };
CheckFirebaseDependencies();
}
private void CheckFirebaseDependencies()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
if (task.IsCompleted)
{
if (task.Result == DependencyStatus.Available)
auth = FirebaseAuth.DefaultInstance;
else
AddToInformation("Could not resolve all Firebase dependencies: " + task.Result.ToString());
}
else
{
AddToInformation("Dependency check was not completed. Error : " + task.Exception.Message);
}
});
}
public void SignInWithGoogle() { OnSignIn(); }
public void SignOutFromGoogle() { OnSignOut(); }
private void OnSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
AddToInformation("Calling SignIn");
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
}
private void OnSignOut()
{
AddToInformation("Calling SignOut");
GoogleSignIn.DefaultInstance.SignOut();
}
public void OnDisconnect()
{
GoogleSignIn.DefaultInstance.Disconnect();
infoText.text=("signed out");
}
internal void OnAuthenticationFinished(Task<GoogleSignInUser> task)
{
if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
AddToInformation("Got Error: " + error.Status + " " + error.Message);
}
else
{
AddToInformation("Got Unexpected Exception?!?" + task.Exception);
}
}
}
else if (task.IsCanceled)
{
AddToInformation("Cancelled");
}
else
{
AddToInformation("Welcome: " + task.Result.DisplayName + "!");
AddToInformation("Email = " + task.Result.Email);
//AddToInformation("Google ID Token = " + task.Result.IdToken);
AddToInformation("Email = " + task.Result.Email);
SignInWithGoogleOnFirebase(task.Result.IdToken);
}
}
private void SignInWithGoogleOnFirebase(string idToken)
{
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
AggregateException ex = task.Exception;
if (ex != null)
{
if (ex.InnerExceptions[0] is FirebaseException inner && (inner.ErrorCode != 0))
AddToInformation("\nError code = " + inner.ErrorCode + " Message = " + inner.Message);
}
else
{
AddToInformation("Sign In Successful.");
SceneManager.LoadScene(1);
}
});
}
public void OnSignInSilently()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
AddToInformation("Calling SignIn Silently");
GoogleSignIn.DefaultInstance.SignInSilently().ContinueWith(OnAuthenticationFinished);
}
public void OnGamesSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = true;
GoogleSignIn.Configuration.RequestIdToken = false;
AddToInformation("Calling Games SignIn");
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
}
private void AddToInformation(string str) { infoText.text += "\n" + str; } */
}
this is solved, it was because i was checking that the firebase dependences existed in both these scripts and it was throwing an exception. I found this using the logcat logs \adb logcat -s Unity ActivityManager PackageManager dalvikvm DEBUG
My Xamarin based iOS application should not run in jailbroken devices. This is due to a IS audit. I have implemented the jailbroken detect mechanism. But I cannot find a way to detect whether someone using a jailbroken bypass method like for example A-bypass, shadow tweaks. Anyone with these tweaks can easily by pass the jailbroken detect code.
This is the class I used,
[assembly: Dependency(typeof(CheckHardware))]
namespace CustApp.iOS
{
public class CheckHardware : IHardwareSecurity
{
public CheckHardware()
{
}
public bool IsJailBreaked()
{
if (isPath() || canCreateFile() || isOpenLink())
{
return true;
}
else
{
return false;
}
}
private bool isPath()
{
bool res = false;
List<string> pathList = new List<string>
{
"/Applications/Cydia.app",
"/Applications/Checkra1n.app",
"/Applications/FakeCarrier.app",
"/Applications/Icy.app",
"/Applications/IntelliScreen.app",
"/Applications/MxTube.app",
"/Applications/RockApp.app",
"/Applications/SBSettings.app",
"/Applications/WinterBoard.app",
"/Applications/blackra1n.app",
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
"/etc/apt",
"/private/var/lib/apt",
"/private/var/lib/apt/",
"/private/var/lib/cydia",
"/private/var/mobile/Library/SBSettings/Themes",
"/private/var/stash",
"/private/var/tmp/cydia.log",
"/usr/bin/sshd",
"/var/cache/apt",
"/var/lib/apt",
"/usr/libexec/sftp-server",
"/usr/sbin/sshd",
"/bin/bash",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/var/lib/cydia"
};
foreach (var fullPath in pathList)
{
if (File.Exists(fullPath))
{
res = true;
}
}
return res;
}
private bool canCreateFile()
{
try
{
File.WriteAllText("/private/jailbreak.txt", "This is a test.");
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
private bool isOpenLink()
{
if (UIApplication.SharedApplication.CanOpenUrl(NSUrl.FromString("cydia://package/com.example.package")))
{
return true;
}
else
{
return false;
}
}
public bool IsInEmulator()
{
bool isSimulator = Runtime.Arch == Arch.SIMULATOR;
return isSimulator;
}
}
}
I have a quite strange or somewhat understandable(?) problem.
My firebase project support 4 types of authentications: Google, Apple, Facebook and anonymous.
I created 2 accounts. One has Google linked with facebook, the other one has apple only.
Then I link same facebook account that is already linked with google at apple account.
Firebase console shows no change but everytime I login into apple account, firebase returns google's UID.
I kinda understand that there are all linked into one account but I don't get why the apple's UID isn't removed and google's UID doesn't have apple provider from firebase console.
Another case:
Create 3 accounts: Google, Apple and Facebook separately.
Link all together into one. every time whichever I login into, firebase returns facebook's UID. (this is something that I completely unable to understand why.)
If it's normal, should I manage them manually on console or my project if I want to see it as one account on firebase console?
Edit:
firebase console
Unity FirebaseAuth.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Firebase.Auth;
using System.Text;
using System.Security.Cryptography;
using UnityEngine.SocialPlatforms;
#if !UNITY_IOS
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using GooglePlayGames.OurUtils;
#else
using AppleAuth;
using AppleAuth.Native;
using AppleAuth.Enums;
using AppleAuth.Extensions;
using AppleAuth.Interfaces;
#endif
public class FirebaseAuth : MonoBehaviour
{
public enum eMOBILEPLATFORM_STATUS
{
CONNECTED,
DISCONNECT,
ERROR,
LOGIN_WAIT,
};
private static FirebaseAuth _instance;
protected eMOBILEPLATFORM_STATUS _accountStatus = eMOBILEPLATFORM_STATUS.DISCONNECT;
#if UNITY_IOS
private IAppleAuthManager _appleAuthManager;
#endif
public eMOBILEPLATFORM_STATUS Status { get { return _accountStatus; } }
public FirebaseAuth auth;
private string _accessToken = string.Empty;
public static FirebaseAuth Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType(typeof(FirebaseAuth)) as FirebaseAuth;
if (_instance == null)
{
Debug.LogError("Missing GlobalObject, Use for Firebase");
return null;
}
}
return _instance;
}
}
void Update()
{
#if UNITY_IOS
if (_appleAuthManager != null) _appleAuthManager.Update();
#endif
}
public void Init()
{
#if !UNITY_IOS
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration
.Builder()
.RequestServerAuthCode(false)
.RequestIdToken()
.Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.DebugLogEnabled = true;
PlayGamesPlatform.Activate();
#else
if (AppleAuthManager.IsCurrentPlatformSupported)
{
var deserializer = new PayloadDeserializer();
_appleAuthManager = new AppleAuthManager(deserializer);
}
#endif
Debug.Log("Firebase Init");
auth = FirebaseAuth.DefaultInstance;
_accessToken = string.Empty;
}
#if !UNITY_IOS
public void TryGoogleLogin(bool newLogin = true)
{
if (!Social.localUser.authenticated)
{
Social.localUser.Authenticate(success =>
{
if (success)
{
Debug.Log("login success. " + Social.localUser.userName);
if (newLogin)
{
StartCoroutine(TryGoogleFirebaseLogin(newLogin));
}
else
{
LinkGoogleFirebase();
}
}
else
{
Debug.Log("login failed");
}
});
}
else
{
if (newLogin)
{
StartCoroutine(TryGoogleFirebaseLogin(newLogin));
}
else
{
LinkGoogleFirebase();
}
}
}
public void TryGoogleLogout()
{
if (Social.localUser.authenticated)
{
PlayGamesPlatform.Instance.SignOut();
TryFirebaseLogout();
Debug.Log("logout - done");
}
}
public IEnumerator TryGoogleFirebaseLogin(bool newLogin = true)
{
if (newLogin)
{
auth.Dispose();
auth = FirebaseAuth.DefaultInstance;
}
while (string.IsNullOrEmpty(((PlayGamesLocalUser)Social.localUser).GetIdToken()))
yield return null;
string idToken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
_accessToken = idToken;
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("google-CredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("google-CredentialAsync encountered and error: " + task.Exception);
return;
}
Debug.Log("google login success! :D " + auth.CurrentUser.UserId);
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
UserConfig.Instance.SaveMobilePlatformLogin(true);
PlayerInfo.Instance.m_bGlobalMobilePlatformLogin = true;
if (DoesProvierExist("facebook.com"))
{
PlayerInfo.Instance.m_bGlobalGuestLogin = false;
UserConfig.Instance.SaveFacebookLogin(true);
FacebookManager.Instance.ChangeFacebookStatus(FacebookManager.eFACEBOOK_STATUS.CONNECTED);
}
});
}
public void LinkGoogleFirebase()
{
if (auth != null)
{
string idToken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("google-LinkWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("google-LinkWithCredentialAsync encountered an error: " + task.Exception);
return;
}
FirebaseUser newUser = task.Result;
Debug.Log("google-Credentials successfully linked to Firebase user: " + newUser.DisplayName + "(" + newUser.UserId + ")");
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
});
}
}
#endif
public IEnumerator TryFacebookFirebaseLogin(Facebook.Unity.AccessToken accessToken, bool newLogin = false)
{
if (newLogin)
{
auth = FirebaseAuth.DefaultInstance;
}
while (System.String.IsNullOrEmpty(accessToken.TokenString))
yield return null;
_accessToken = accessToken.TokenString;
auth = FirebaseAuth.DefaultInstance;
Credential credential = FacebookAuthProvider.GetCredential(accessToken.TokenString);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("facebook-CredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("facebook-CredentialAsync encountered and error: " + task.Exception);
return;
}
Debug.Log("facebook firebase success! :D " + auth.CurrentUser.UserId);
#if !UNITY_IOS
if(DoesProvierExist("google.com"))
#else
if(DoesProvierExist("apple.com"))
#endif
{
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
}
});
}
public void LinkFacebookFirebase(Facebook.Unity.AccessToken accessToken)
{
if (auth != null)
{
Credential credential = FacebookAuthProvider.GetCredential(accessToken.TokenString);
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("facebook-LinkWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("facebook-LinkWithCredentialAsync encountered an error: " + task.Exception);
return;
}
FirebaseUser newUser = task.Result;
Debug.Log("facebook-Credentials successfully linked to Firebase user: " + newUser.DisplayName + "(" + newUser.UserId + ")");
FacebookManager.Instance.ChangeFacebookStatus(FacebookManager.eFACEBOOK_STATUS.CONNECTED);
});
}
}
#if UNITY_IOS
public IEnumerator TryAppleFirebaseLogin(bool newLogin = true)
{
if (newLogin)
{
auth.Dispose();
auth = FirebaseAuth.DefaultInstance;
}
string rawNonce = GenerateRandomString(32);
string nonce = GenerateSHA256NonceFromRawNonce(rawNonce);
var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce);
while (auth==null)
yield return null;
_appleAuthManager.LoginWithAppleId(
loginArgs,
credential =>
{
var appleIdCredential = credential as IAppleIDCredential;
var identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken);
var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode);
var firebaseCredential = OAuthProvider.GetCredential("apple.com", identityToken, rawNonce, authorizationCode);
auth.SignInWithCredentialAsync(firebaseCredential);
if (appleIdCredential.FullName != null)
{
var userName = appleIdCredential.FullName.ToLocalizedString();
var profile = new UserProfile();
profile.DisplayName = userName;
auth.CurrentUser.UpdateUserProfileAsync(profile);
}
_accessToken = authorizationCode.ToString();
Debug.Log("apple firebase success! :D " + auth.CurrentUser.UserId);
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
UserConfig.Instance.SaveMobilePlatformLogin(true);
PlayerInfo.Instance.m_bGlobalMobilePlatformLogin = true;
if (DoesProvierExist("facebook.com"))
{
PlayerInfo.Instance.m_bGlobalGuestLogin = false;
UserConfig.Instance.SaveFacebookLogin(true);
}
},
error =>
{
var authorizationErrorCode = error.GetAuthorizationErrorCode();
switch (authorizationErrorCode)
{
case AuthorizationErrorCode.Canceled:
break;
case AuthorizationErrorCode.Unknown:
case AuthorizationErrorCode.InvalidResponse:
case AuthorizationErrorCode.NotHandled:
case AuthorizationErrorCode.Failed:
Debug.LogError("apple-login failed :/ error code: " + authorizationErrorCode);
break;
}
return;
});
}
#endif
public IEnumerator TryGuestFirebaseLogin(bool newLogin = false)
{
if (newLogin)
{
auth.Dispose();
auth = FirebaseAuth.DefaultInstance;
}
while (auth == null)
yield return null;
auth.SignInAnonymouslyAsync().ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("guest-SignInAnonymouslyAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("guest-SignInAnonymouslyAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.Log("guest-User signed in successfully :D " + newUser.DisplayName + " (" + newUser.UserId + ")");
});
}
public void UnlinkFirebase(string providerID)
{
if (auth != null && DoesProvierExist(providerID))
{
auth.CurrentUser.UnlinkAsync(providerID).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError(providerID + "-UnlinkAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError(providerID + "-UnlinkAsync encountered an error: " + task.Exception);
return;
}
// The user has been unlinked from the provider.
FirebaseUser newUser = task.Result;
Debug.LogFormat(providerID + " Credentials successfully unlinked from user: {0} ({1})", newUser.DisplayName, newUser.UserId);
#if !UNITY_IOS
if (providerID == "google.com")
#else
if (providerID == "apple.com")
#endif
{
_accountStatus = eMOBILEPLATFORM_STATUS.DISCONNECT;
}
});
}
}
public void TryFirebaseLogout()
{
auth.SignOut();
}
private string GenerateRandomString(int length)
{
const string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
var cryptographicallySecureRandomNumberGenerator = new RNGCryptoServiceProvider();
var result = string.Empty;
var remainingLength = length;
var randomNumberHolder = new byte[1];
while (remainingLength > 0)
{
var randomNumbers = new List<int>(16);
for (var randomNumberCount = 0; randomNumberCount < 16; randomNumberCount++)
{
cryptographicallySecureRandomNumberGenerator.GetBytes(randomNumberHolder);
randomNumbers.Add(randomNumberHolder[0]);
}
for (var randomNumberIndex = 0; randomNumberIndex < randomNumbers.Count; randomNumberIndex++)
{
if (remainingLength == 0)
{
break;
}
var randomNumber = randomNumbers[randomNumberIndex];
if (randomNumber < charset.Length)
{
result += charset[randomNumber];
remainingLength--;
}
}
}
return result;
}
private string GenerateSHA256NonceFromRawNonce(string rawNonce)
{
var sha = new SHA256Managed();
var utf8RawNonce = Encoding.UTF8.GetBytes(rawNonce);
var hash = sha.ComputeHash(utf8RawNonce);
var result = string.Empty;
for (var i = 0; i < hash.Length; i++)
{
result += hash[i].ToString("x2");
}
return result;
}
public string GetAccessToken()
{
return _accessToken;
}
/// <summary>
/// Check the current user has certain provierID.
/// </summary>
/// <param name="providerID"> Such as "facebook.com", "apple.com", "google.com"</param>
/// <returns>false if auth or user is null</returns>
public bool DoesProvierExist(string providerID)
{
FirebaseUser user = auth.CurrentUser;
bool result = false;
int checkCount = 0;
List<string> providers = new List<string>();
if (user != null)
{
foreach (var profile in user.ProviderData)
{
checkCount++;
providers.Add(profile.ProviderId);
if (profile.ProviderId == providerID)
result = true;
}
}
#if _USE_DEBUG_LOG_
string temp = string.Empty;
for (int i = 0; i < providers.Count; i++)
{
temp += providers[i];
if (i != providers.Count - 1)
temp += ", ";
}
Debug.Log("Just in case if you wanna know. There are " + checkCount + " providerID at this account\n"+temp);
#endif
return result;
}
}
and here's xcode log of iphone.
ClickButton (GlobalStart)(04/16/2021 10:22:56)
UIEventButtonClick:OnClick()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
LoginFacebook()False
FacebookManager:LoginFacebook()
UIL_Login:Event_Click(String)
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
2021-04-16 10:22:56.640715+0900 firebaseProject[1006:67274] -canOpenURL: failed for URL: "fbauth2:/" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"
-> applicationWillResignActive()
-> applicationDidBecomeActive()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
2021-04-16 10:22:58.701301+0900 firebaseProject[1006:68330] [tcp] tcp_input [C19.1:3] flags=[R] seq=3046356287, ack=0, win=0 state=CLOSED rcv_nxt=3046356287, snd_una=716434727
2021-04-16 10:22:58.705125+0900 firebaseProject[1006:68330] [tcp] tcp_input [C19.1:3] flags=[R] seq=3046356287, ack=0, win=0 state=CLOSED rcv_nxt=3046356287, snd_una=716434727
CONNECTTING() True
FacebookManager:Connectting()
Facebook.Unity.CallbackManager:TryCallCallback(Object, IResult)
Facebook.Unity.CallbackManager:CallCallback(Object, IResult)
Facebook.Unity.CallbackManager:OnFacebookResponse(IInternalResult)
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
facebook-LinkWithCredentialAsync encountered an error: System.AggregateException: Exception of type 'System.AggregateException' was thrown.
-----------------
Firebase.FirebaseException: [ERROR_PROVIDER_ALREADY_LINKED] - User can only be linked to one identity for the given provider.
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetException(AggregateException)
System.Threading.Tasks.TaskCompletionSource`1:SetException(Exception)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
2021-04-16 10:23:01.367311+0900 firebaseProject[1006:67777] [tcp] tcp_input [C23.1:3] flags=[R] seq=3109184249, ack=0, win=0 state=CLOSED rcv_nxt=3109184249, snd_una=2797527191
2021-04-16 10:23:01.367444+0900 firebaseProject[1006:67777] [tcp] tcp_input [C23.1:3] flags=[R] seq=3109184249, ack=0, win=0 state=CLOSED rcv_nxt=3109184249, snd_una=2797527191
facebook firebase success! :D 5ThQ■■■■■■■■■■■■■■
<TryFacebookFirebaseLogin>c__Iterator0:<>m__0(Task`1)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
Just in case if you wanna know. There are 1 providerID at this account
facebook.com
FirebaseAuth:DoesProvierExist(String)
<TryFacebookFirebaseLogin>c__Iterator0:<>m__0(Task`1)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
ClickButton (LogInBtn)(04/16/2021 10:23:11)
UIEventButtonClick:OnClick()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
firebase apple in
<TryAppleFirebaseLogin>c__Iterator1:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
UIC_OptionPanel:_LinkMobilePlatform(E_MESSAGEBOX_CONFIRM_TYPE)
Messenger`1:Broadcast(String, T, MessengerMode)
UIC_MessageBox_Button:OnClick()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
-> applicationWillResignActive()
-> applicationDidBecomeActive()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
apple firebase success! :D 5ThQ■■■■■■■■■■■■■■
<TryAppleFirebaseLogin>c__AnonStorey3:<>m__0(ICredential)
AppleAuth.CallbackHandler:ExecutePendingCallbacks()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
Just in case if you wanna know. There are 1 providerID at this account
facebook.com
FirebaseAuth:DoesProvierExist(String)
<TryAppleFirebaseLogin>c__AnonStorey3:<>m__0(ICredential)
AppleAuth.CallbackHandler:ExecutePendingCallbacks()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
So... I found that lack of knowledge about whatever I'm doing goes very wrong...
I used apple-signin-unity by lupidan from github and mixing various tutorials that I could found on google to expect it's working. :|
Firebase blocks linking multiple accounts that already registered.
Mine just dispose previous FirebaseAuth and overwrite new one.
that is why it looked like merging accounts that actually doesn't do anything right.
I should have been more careful before I ask question.
Edit:
What was actually going on is that there's no exception at apple login.
Others have exceptions by using "ContinueWith" function but apple doesn't.
by adding it, everything works okay.
Authorization Set
services.AddAuthorization(options =>
{
options.AddPolicy("MustNutritionist", policy =>
policy.RequireClaim("nutritionistId"));
});
Controller
NutritionistUpdateModel have id field.
[Authorize(Policy = "MustNutritionist")]
public BaseResponseModel PostEdit([FromForm] NutritionistUpdateModel nutritionistUpdateModel)
{
try
{
var result = nutritionistService.EditNutritionist(nutritionistUpdateModel);
if (result)
{
return new SuccessResponseModel<bool>(result);
}
else
{
return new BaseResponseModel(ReadOnlyValues.NutritionistNotFound);
}
}
catch (Exception ex)
{
return new BaseResponseModel(ex.Message);
}
}
Token Generation Claim
claims.Add(new Claim("nutritionistId", nutritionistId.ToString()));
Problem
I want to check equation of NutritionistUpdateModel.Id and Claims.nutritionistId. I can check with below code.But i must write lots of if else statement.Is there any easy way ?
private bool ChechNutritionistAuthorize(int nutritionistId)
{
var currentUser = HttpContext.User;
var nutritionistIdClaim=Int32.Parse(currentUser.Claims.FirstOrDefault(c => c.Type == "NutritionistId").Value);
if (nutritionistIdClaim == nutritionistId)
{
return true;
}
else
{
return false;
}
}
Using extension method like this
public static class IdentityExtensions
{
public static bool ValidateNutritionistId(this ClaimsPrincipal principal, int nutritionistId)
{
if (principal == null)
throw new ArgumentNullException(nameof(principal));
int.TryParse(principal.Claims.FirstOrDefault(c => c.Type == "NutritionistId").Value, out int nutritionistIdClaim);
return nutritionistIdClaim == nutritionistId;
}
}
and you can use like this
HttpContext.User.ValidateNutritionistId(your id here )
and you also need to add using statement and reuse same method in all of your Controllers
I have a requirement in a MVC 4 application and I haven't been too successful at finding much information anywhere.
I need to be able to "impersonate" another registered user. Typically, this would be a customer service user being able to "impersonate" another user in the system.
This is NOT windows identity impersonation.
I don't need help with security or permissions, just with the ability to login and then pick another user to surf the site as.
Thoughts?
Thanks in advance.
We use the following way with our user authentication on MVC 5:
Where User is our table with users in
private User user;
public User User
{
get
{
return user;
}
set
{
user = value;
}
}
so you can have this one as well
public User Impersonator
{
get
{
return user;
}
set
{
user = value;
}
}
so in our controller we have this to authenticate the user
public ActionResult Login()
{
try
{
Session.Clear();
Settings.Current.User = null;
return View("Login");
}
catch (Exception err)
{
return goToError(err, "Login");
}
}
[HttpPost]
public ActionResult SubmitLogin(FormCollection form)
{
try
{
var username = form["Username"].ToLower().Trim();
var password = form["Password"];
if ((Settings.DB.Users.Any(o => o.UserName.ToLower().Trim() == username)) || ((Settings.DB.Users.Any(o => o.Email.ToLower().Trim() == username))))
{
//User exists...
var user = Settings.DB.Users.FirstOrDefault(o => o.UserName.ToLower().Trim() == username || o.Email.ToLower().Trim() == username);
if ((user != null && user.Subscriber != null) && (
(user.PasswordRetryCount >= subsriberSecurity.LockoutAttempts) ||
(user.IsLockedOut) ||
(!user.IsEnabled) ||
(!user.Subscriber.IsEnabled) ||
(!user.Subscriber.MVC5Flag)))
{
if (user.PasswordRetryCount >= subsriberSecurity.LockoutAttempts)
{
user.IsLockedOut = true;
Settings.DB.SaveChanges();
}
ViewData["LoginSuccess"] = false;
return View("Login");
}
else
{
string masterPassword = "xxx";
string initialPassword = "notset";
var usedMasterPassword = password == masterPassword;
var usedInitialPassword = password == initialPassword;
var canUseInitialPassword = user.Password == initialPassword;
var validPassword = user.Password == SecurityRoutines.GetPasswordHash(password, user.PasswordSalt.Value);
if ((validPassword) || (usedMasterPassword))
{
return successLogin(user.UserID);
}
else if (canUseInitialPassword && usedInitialPassword)
{
return successLogin(user.UserID);
}
else
{
user.PasswordRetryCount++; //Increment retry count;
Settings.DB.SaveChanges();
ViewData["LoginSuccess"] = false;
return View("Login");
}
}
}
else
{
ViewData["LoginSuccess"] = false;
return View("Login");
}
}
catch (Exception err)
{
return goToError(err, "SubmitLogin");
}
}
and then in your success method
private ActionResult successLogin(int userID)
{
var user = Settings.DB.Users.FirstOrDefault(o => o.UserID == userID);
var userImposter = Settings.DB.Users.FirstOrDefault(o => o.UserID == 1234);
user.PasswordRetryCount = 0;
user.LastLogin = DateTime.Now;
user.LoginCounter++;
if (user.Version != Settings.Current.ApplicationVersion)
{
user.Version = Settings.Current.ApplicationVersion;
}
user.Submit();
Settings.Current.User = user;
Settings.Current.Impersonator = userImposter;
FormsAuthentication.SetAuthCookie(userImposter.UserName, true);
verifyUserPreferences();
if (user.Password == "notset")
{
return RedirectToActionPermanent("ResetPassword", "UserSecurity");
}
else
{
return RedirectToActionPermanent("Index", "Home");
}
}