I am integrating Azure in my app.I have created app at Azure portal in Active directory and for integration using ADAL library but when i am running the app getting login screen of Microsoft and after login getting error this.
i am getting this error
For login created button and onclick on button calling this
if (mResult != null) {
// logout
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
CookieSyncManager.getInstance().sync();
authenticationContext.getCache().removeAll();
} else {
// login
authenticationContext.acquireToken(LoginActivity.this,Constant.CLIENT_ID,
Constant.CLIENT_SECRETE_KEY, Constant.REDIRECT_URL, "", PromptBehavior.Auto, "",
callback);//CLIENT_ID=my appid at the of app registration //CLIENT_SECRETE_KEY=secret key of registered app in Active Directory //REDIRECT_URL=passing valid url
}
and initializing authenticationcontext in oncreate() of LoginActivity
authenticationContext = new AuthenticationContext(LoginActivity.this,
Constant.AUTHORITY_URL, true);// Authority_URL=https://login.windows.net/mydirectoryname.onmicrosoft.com
for callback
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
authenticationContext.onActivityResult(requestCode, resultCode, data);
}
private void showInfo(String msg) {
Log.e("", msg);
}
private AuthenticationCallback<AuthenticationResult> callback = new AuthenticationCallback<AuthenticationResult>() {
#Override
public void onError(Exception exc) {
showInfo("getToken Error:" + exc.getMessage());
}
#Override
public void onSuccess(AuthenticationResult result) {
mResult = result;
startActivity(new Intent(LoginActivity.this, SecondActivity.class));
if (mResult.getUserInfo() != null) {
Log.v("", "User info userid:" + result.getUserInfo().getUserId()
+ " displayableId:" + result.getUserInfo().getDisplayableId());
}
}
};
and in Azure Portal in app registration grand the permission of KEYVAULT and MicrosoftAzureActiveDirectory (sign in and read user profile permission)
What i am doing wrong?
Your parameters are probably wrong. Check this example on GitHub: https://github.com/Azure-Samples/active-directory-android/blob/master/TaskApplication/src/main/java/com/microsoft/aad/test/todoapi/ToDoActivity.java#L188.
There it is done with:
mAuthContext.acquireToken(ToDoActivity.this, Constants.RESOURCE_ID,
Constants.CLIENT_ID, Constants.REDIRECT_URL, Constants.USER_HINT,
new AuthenticationCallback<AuthenticationResult>() {
#Override
public void onError(Exception exc) {
if (mLoginProgressDialog.isShowing()) {
mLoginProgressDialog.dismiss();
}
Toast.makeText(getApplicationContext(),
TAG + "getToken Error:" + exc.getMessage(), Toast.LENGTH_SHORT)
.show();
navigateToLogOut();
}
#Override
public void onSuccess(AuthenticationResult result) {
if (mLoginProgressDialog.isShowing()) {
mLoginProgressDialog.dismiss();
}
if (result != null && !result.getAccessToken().isEmpty()) {
setLocalToken(result);
sendRequest();
} else {
navigateToLogOut();
}
}
});
You shouldn't have your client secret in the mobile app anyway. Anyone can unpack you application and find it.
if (result != null && !result.getAccessToken().isEmpty()) {
is wrong, add token null check or add getStatus success check...
yes, ms special create bad android sample [ I think :) ];
simplest way is open your app creted under AD and open edit manifest:
from sample:
AUTHORITY_URL - is "identifierUris" from app manifest (not android manifest; add-manifest from ad registered web-api app);
CLIENT_ID - is appId;
RESOURCE_ID - is from manifest too;
"requiredResourceAccess": [ { "resourceAppId": some times it comes in auth ex message;
and you should add same reply Url at AD app too;
if redirect after auth directly to todoactivity for some reason result failed status, but if open add user you can see there sign-in user info and sign in success status;
So after fix that sample it works at all, but it was a hard 1-2 days brainstorm;
expected more form ms sample, looks like with each year qulity is go momre and more low;
Related
I am testing out my app for Android which uses Uber API to login, extracted from the uber api example (pretty much unchanged from the SSO button), and it works as intended for most of my testers and me, on both my sample devices and emulator, but on a couple of devices I am getting my "onLoginCancel" called after the login process successfully completes.
The user clicks on sign on, the uber app appears to open and then proceeds to ask for permission, when the user clicks to allow the app, it returns to my login screen with the user cancelled message. There is no message on my debug log pointing to this issue (other then a "Login Cancelled" one), and no errors appear to occur. I am having a hard time finding out what is happening since I am not getting an error message with the failed attempt, is there any way to get an error message out of this situation? Any ideas as to what could be causing the problem?
Both devices that are having this issue are samsungs, one a tablet (the tester couldn`t say exactly which tablet) and one a Samsung Galaxy Ace 4 Lite Duos SM-G313M, both devices have Android version 4.4.2.
EDIT: To better show what I am doing, I will place bellow a resumed version of my app code with only the login stuff. The login screen is just a normal screen showing a button that uses SSO with uber.
public static final String CLIENT_ID = BuildConfig.CLIENT_ID;
public static final String REDIRECT_URI = "http://localhost:8000";
private static final String LOG_TAG = "LoginActivity";
private static final int CUSTOM_BUTTON_REQUEST_CODE = 1113;
private Button customButton;
private AccessTokenManager accessTokenManager;
private LoginManager loginManager;
private SessionConfiguration configuration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
configuration = new SessionConfiguration.Builder()
.setClientId(CLIENT_ID)
.setRedirectUri(REDIRECT_URI)
// same issue with PRODUCTION environment
.setEnvironment(SessionConfiguration.Environment.SANDBOX)
.setScopes(Arrays.asList(Scope.PROFILE, Scope.RIDE_WIDGETS))
.build();
validateConfiguration(configuration);
accessTokenManager = new AccessTokenManager(this);
//Use a custom button with an onClickListener to call the LoginManager directly
loginManager = new LoginManager(accessTokenManager,
new MyLoginCallback(),
configuration,
CUSTOM_BUTTON_REQUEST_CODE);
customButton = (Button) findViewById(R.id.custom_uber_button);
customButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginManager.login(LoginActivity.this);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(LOG_TAG, String.format("onActivityResult requestCode:[%s] resultCode [%s]",
requestCode, resultCode));
if (requestCode == CUSTOM_BUTTON_REQUEST_CODE) {
//Allow each a chance to catch it.
loginManager.onActivityResult(this, requestCode, resultCode, data);
}
}
private class MyLoginCallback implements LoginCallback {
#Override
public void onLoginCancel() {
Log.d(LOG_TAG, "Login cancel");
Toast.makeText(LoginActivity.this, R.string.user_cancels_message, Toast.LENGTH_LONG).show();
}
#Override
public void onLoginError(#NonNull AuthenticationError error) {
Log.d(LOG_TAG, "Login error: " + error.name());
Toast.makeText(LoginActivity.this,
getString(R.string.login_error_message, error.name()), Toast.LENGTH_LONG)
.show();
}
#Override
public void onLoginSuccess(#NonNull AccessToken accessToken) {
Intent myIntent = new Intent(LoginActivity.this, Main.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(myIntent);
}
#Override
public void onAuthorizationCodeReceived(#NonNull String authorizationCode) {
}
}
/**
* Validates the local variables needed by the Uber SDK used in the sample project
* #param configuration
*/
private void validateConfiguration(SessionConfiguration configuration) {
String nullError = "%s can't be empty";
String sampleError = "Please update your %s in the gradle.properties of the project before " +
"using the Uber SDK Sample app. For a more secure storage location, " +
"please investigate storing in your user home gradle.properties ";
checkNotNull(configuration, String.format(nullError, "SessionConfiguration"));
checkNotNull(configuration.getClientId(), String.format(nullError, "Client ID"));
checkNotNull(configuration.getRedirectUri(), String.format(nullError, "Redirect URI"));
checkState(!configuration.getClientId().equals("insert_your_client_id_here"),
String.format(sampleError, "Client ID"));
checkState(!configuration.getRedirectUri().equals("insert_your_redirect_uri_here"),
String.format(sampleError, "Redirect URI"));
}
Upon running the app, these are the only logs I get, no error or anything:
03-21 13:32:19.788 5035-5035/com.mycomp.myapp I/LoginActivity: onActivityResult requestCode:[1113] resultCode [0]
03-21 13:32:19.838 5035-5035/com.mycomp.myapp D/LoginActivity: Login cancel
I am working with ADAL from
https://github.com/Azure-Samples/active-directory-android
My code mimics the sample very close
mAuthContext.acquireToken(ToDoActivity.this, Constants.RESOURCE_ID,
Constants.CLIENT_ID, Constants.REDIRECT_URL, Constants.USER_HINT,
new AuthenticationCallback<AuthenticationResult>() {
#Override
public void onError(Exception exc) {
if (mLoginProgressDialog.isShowing()) {
mLoginProgressDialog.dismiss();
}
Toast.makeText(getApplicationContext(),
TAG + "getToken Error:" + exc.getMessage(), Toast.LENGTH_SHORT)
.show();
navigateToLogOut();
}
#Override
public void onSuccess(AuthenticationResult result) {
if (mLoginProgressDialog.isShowing()) {
mLoginProgressDialog.dismiss();
}
if (result != null && !result.getAccessToken().isEmpty()) {
setLocalToken(result);
sendRequest();
} else {
navigateToLogOut();
}
}
});
I pass in the user's email address, but if the user changes it and uses a different one the ADAL library on the onSuccess never tells me the user changed it. The AuthenticationResult has a field calls mUserInfo that that should contain user's first name/last name email etc.
But for me every successful login mUserInfo=null.
Anyone know how to get ADAL to return a fully populated mUserInfo object?
thanks
Tom
Userinfo is constructed from the ID_token retuned from the server. In case of adfs blue (3.0), it does not return an ID_token and hence you cannot truly know what user signed in at the IDP. Adfs threshold supports ID_token if you can upgrade.
I want to implement Facebook Login in my application, but here I am getting problem while trying to login i.e :
**{Session state:OPENING, token:{AccessToken token:ACCESS_TOKEN_REMOVED permissions:[]}, appId:1xxxxxxxxxxxxxxx}**
and sometimes this one also:
**{Session state:CLOSED, token:{AccessToken token:ACCESS_TOKEN_REMOVED permissions:[]}, appId:1xxxxxxxxxxxxxxx}**
Note: The above problem occurs when my device already has installed NATIVE FACEBOOK APP, if I uninstall the Facebook app it works absolutely fine. Can Anyone please help me out what the matter is ?
Thanks in advance
Be sure to override in your Activity the onActivityResult method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
Try
AccessToken.getCurrentAccessToken().getToken();
instead of using the toString() function.
I know this is an old ticket, but no one has appeared to give the correct answer. The token is removed from toString to prevent token exposure.
com.facebook.LoggingBehavior (from line 29):
/**
* Indicates that access tokens should be logged as part of the request logging; normally they are not.
*/
INCLUDE_ACCESS_TOKENS,
com.facebook.AccessToken (from line 322):
private String tokenToString() {
if (this.token == null) {
return "null";
} else if (Settings.isLoggingBehaviorEnabled(LoggingBehavior.INCLUDE_ACCESS_TOKENS)) {
return this.token;
} else {
return "ACCESS_TOKEN_REMOVED";
}
}
To show the token in toString requests simply add logging to the settings :
Settings.addLoggingBehavior( LoggingBehavior.INCLUDE_ACCESS_TOKENS );
this.mUiLifecycleHelper = new UiLifecycleHelper( this, this.mCallback );
this.mUiLifecycleHelper.onCreate( savedInstanceState );
Hope this helps others with the same issue.
Just a heads up.
This exact case was happening to me. My login stopped working just because I changed my Activity launch mode in Manifest.xml file from:
android:launchMode="singleInstance"
to
android:launchMode="singleTask"
So, I changed it again to singleInstance and it is working fine now.
This maybe happening because you didn't add the hashkey in your Facebook app. Check out this link Generating Hashkey for Android to learn how to generate hashkey.
This was happening to me too. It started working after i added the hashkey in Facebook app.
This is my working integration of new Facebook SDK 4.1.
First you need to init SDKin 4.1 ///
/** if face book SDK is not initialized then initialized.*/
if(!FacebookSdk.isInitialized())
FacebookSdk.sdkInitialize(BaseActivity.this);
Now you need callback manger
/** create face book callback factory.*/
if(null == callbackManager)
callbackManager = CallbackManager.Factory.create();
These are call back.
public final FacebookCallback<LoginResult> _mcallbackLogin = new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
if(loginResult.getAccessToken() != null){
Log.i("TAG", "LoginButton FacebookCallback onSuccess token : "+ loginResult.getAccessToken().getToken());
GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
if(null != object){
Log.e("TAG", object.optString("name"),object.optString("first_name"),object.optString("email"),false).execute();
}
}
}).executeAsync();
}
}
#Override
public void onCancel() {
Log.e("TAG", "LoginButton FacebookCallback onCancel");
}
#Override
public void onError(FacebookException exception) {
Log.e("TAG","Exception:: "+exception.getStackTrace());
}
};
Now you need register call back on facebook login button
loginBtn.registerCallback(BaseActivity.callbackManager,_mcallbackLogin);
I'm writing an Android application that should upload photos to Facebook.
Everything works just fine except one thing. When I called the Facebook.authorize() method for the first time the Facebook dialog was shown with requested permissions and 'Allow'/'Don't Allow' buttons. That was OK. But when I run my app for the secong time I've got the same dialog, but with message that my application allowed already and suggestion to press OK button.
Is there a way to avoid this second dialog? Should I skip the authorize method in some conditions?
I tried to call the Facebook.isSessionValid() method before authorize method, but this did not help.
Here is my simplified code:
mFacebook = new Facebook(APPLICATION_ID);
mFacebookAsync = new AsyncFacebookRunner(mFacebook);
if (mFacebook.isSessionValid()) {
uploadPictureFile();
}
else {
mFacebook.authorize(this, new String[] {"publish_stream"}, new Facebook.DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
Toast.makeText(PhotoFeederFacebookSendActivity.this, "Facebook error: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
finishWithResultCode(RESULT_CANCELED);
}
#Override
public void onError(DialogError e) {
Toast.makeText(PhotoFeederFacebookSendActivity.this, "Facebook dialog error: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
finishWithResultCode(RESULT_CANCELED);
}
#Override
public void onComplete(Bundle values) {
uploadPictureFile();
}
#Override
public void onCancel() {Toast.makeText(PhotoFeederFacebookSendActivity.this, "Facebook authorization cancelled.", Toast.LENGTH_LONG).show();
finishWithResultCode(RESULT_CANCELED);
}
});
}
And here is my onActivityResult method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mFacebook.authorizeCallback(requestCode, resultCode, data);
}
Any help appreciated. Thanks.
You need to call mFacebook.setAccessToken("your token") before mFacebook.isSessionValid()
and you need to save the token to preference yourself
If you only intend to update status see my post here...
Android Facebook Graph API to update status
I am using the Android code below to connect to Facebook but getting the following exception instead of running the function onLoginSuccess:
Facebook Server Error + 104 - Incorrect signature
public class FacebookConnection extends Activity implements LoginListener {
private FBRocket fbRocket;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// You need to put in your Facebook API key here:
fbRocket = new FBRocket(this, "test", "e2c8deda78b007466c54f48e6359e02e");
// Determine whether there exists a previously-saved Facebook:
if (fbRocket.existsSavedFacebook()) {
String str =fbRocket.getAPIKey();
Log.e("Api key", str);
fbRocket.loadFacebook();
} else {
fbRocket.login(R.layout.main);
String str =fbRocket.getAPIKey();
Log.e("Api key", str);
}
}
public void onLoginFail() {
fbRocket.displayToast("Login failed!");
fbRocket.login(R.layout.main);
}
public void onLoginSuccess(Facebook facebook) {
fbRocket.displayToast("Login success!******************");
// Set the logged-in user's status:
try {
facebook.setStatus("I am using Facebook -- it's great!");
String uid = facebook.getFriendUIDs().get(0); // Just get the uid of the first friend returned...
fbRocket.displayDialog("Friend's name: " + facebook.getFriend(uid).name); // ... and retrieve this friend's name.
} catch (ServerErrorException e) {
// Check if the exception was caused by not being logged-in:
if (e.notLoggedIn()) {
// ...if it was, then login again:
fbRocket.login(R.layout.main);
} else {
System.out.println(e);
e.printStackTrace();
}
}
}
}
I've had many problems using FBRocket because of there's not many documentation about it.
Try editing your Facebook app in your Facebook Site as a "Desktop App" not as a "Web app". You have to go to "Advanced" -> Application type
I had the exact same problem, though at a different place. After doing a fair amount of digging, I found that the call to fbRocket.loadFacebook() was the culprit. I can't get that method to work, even if I do a facebook.save() to save the session to disk after a manual login. All I can think is that fbRocket.loadFacebook() does not work properly and you should always use fbRocket.login(). That is what I have to do in my app. I also couldn't get it to work with the sample code on the FBRocket website. Hope that helps.
Chuck
public class FacebookConnection extends Activity implements LoginListener {
private FBRocket fbRocket;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// You need to put in your Facebook API key here:
fbRocket = new FBRocket(this, "test", "e2c8deda78b007466c54f48e6359e02e");
// Determine whether there exists a previously-saved Facebook:
if (fbRocket.existsSavedFacebook()) {
String str =fbRocket.getAPIKey();
Log.e("Api key", str);
fbRocket.loadFacebook();
} else {
fbRocket.login(R.layout.main);
String str =fbRocket.getAPIKey();
Log.e("Api key", str);
}
}
public void onLoginFail() {
fbRocket.displayToast("Login failed!");
fbRocket.login(R.layout.main);
}
public void onLoginSuccess(Facebook facebook) {
fbRocket.displayToast("Login success!******************");
// Set the logged-in user's status:
try {
facebook.setStatus("I am using Facebook -- it's great!");
String uid = facebook.getFriendUIDs().get(0); // Just get the uid of the first friend returned...
fbRocket.displayDialog("Friend's name: " + facebook.getFriend(uid).name); // ... and retrieve this friend's name.
} catch (ServerErrorException e) {
// Check if the exception was caused by not being logged-in:
if (e.notLoggedIn()) {
// ...if it was, then login again:
fbRocket.login(R.layout.main);
} else {
System.out.println(e);
e.printStackTrace();
}
}
}
}