Using the ADAL library with a government account, the authorization token request fails due to a server timeout. The token is needed to make EWS calls to the server. The authority being used is "https://logon.microsoftonline.us". The resource is "https://outlook.office.us".
There is no issue when retrieving a token from a public tenant (our company tenant) and our product. We receive the token using ""https://logon.microsoftonline.com". The resource is "https://outlook.office.com".
We can access the server with the same credentials at "https://owa.us.af.mil/f5-w-{REDACTED}/adfs/ls/?client-request-id={REDACTED}". But ADAL times out with "https://federation.us.af.mil/adfs/ls/?login_hint={REDACTED}.af.mil&client-request-id={REDACTED}&username={REDACTED}.af.mil&wa=wsignin1.0&wtrealm={REDACTED}"
Does the government server have the proper ADFS configuration? If so, what would be the probable solution?
Is our tenant setup correctly? Do we need a public tenant for public app access and a government tenant for government clients? Or can those be interchangeable?
We setup a public and a government AAD app to handle token requests. We thought that could have been the issue. No change. I also did several variations on the authority and resources used in the request. No change. I even tapped into ADAL and use our HTTPS protocol instead of the standard Apple HTTPS protocol.
Below is the context setup and token call method used.
let authContext = ADAuthenticationContext(authority: authority, validateAuthority: true, error: &error)
authContext?.credentialsType = AD_CREDENTIALS_EMBEDDED
authContext?.acquireToken(withResource: self.resource, clientId: self.clientId, redirectUri: self.redirectUri,
userId: self.userID!, completionBlock: { result in })
The token request will always timeout at this point:
ADAL 2.7.5 iOS Sim 12.1 [2018-12-12 17:14:38 - F06F784C-7F5B-4231-BE34-714AF8204357] -webAuthDidFailWithError: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x600002fa5380 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "The request timed out." UserInfo={NSErrorFailingURLStringKey=https://federation.us.af.mil/adfs/ls/?login_hint={REDACTED}.af.mil&client-request-id={REDACTED}&username={REDACTED}.af.mil&wa=wsignin1.0&wtrealm={REDACTED}
The user experiences a pop up window with a blank screen. The window would normally show text asking for permission to use the app. A timeout message hits about 60 seconds later.
apologies for the delayed response on this. Instead of outlook.office365.us, the resource you should be using is either portal.apps.mil or outlook-dod.office365.us.
Does that help?
Related
We are trying to implement OIDC for user onboarding from our main platform to our secondary platform
While calling AutomaticSilentRenew function it leaves the following error:
Is there anything wrong here (PFA)
OIDC config Object:
VUE_APP_OIDC_CONFIG={"authority": "https://auth.mainPlatform.com", "clientId": "<client-id>", "redirectUri": "http://localhost:8080/oidc-callback", "popupRedirectUri": "http://localhost:8080/oidc-popup-callback", "responseType": "id_token token", "scope": "openid email", "automaticSilentRenew": true, "automaticSilentSignin": true, "silentRedirectUri": "http://localhost:8080/silent-renew-oidc.html"}
Error:
{context: "authenticateOidcSilent", error: "login_required"} App.vue?234e:38 I am listening to the oidc error event in vuex-oidc context: "authenticateOidcSilent" error: "login_required"
That's an absolutely standard part of the silent renewal flow and can happen for 2 reasons:
When the Authorization Server Session Cookie expires
If a browser drops the AS session cookie - eg Safari is likely to do this in 2020
The usual action when you get a login_required error code is to redirect the user to sign in again.
TROUBLESHOOTING
If this is happening on every token renewal request, I would debug via a tool such as Fiddler to see if the cookie is being sent. Your problem might be caused by recent browser restrictions on cross domain cookies.
For something to compare against, see my Silent Token Renewal blog post.
I have set up a Cognito authorizer with an App client that is connected to Google Identity Provider.
"Callback URL" is http://localhost and "Sign out URL" is http://localhost/logout. I have enabled the "Authorization code grant" and the "Implicit grant" flows and the I want to implement the following flow :
User sends a GET request to the LOGIN endpoint (/login) which is the following:
https://mycognAuthorizer.auth.eu-west-1.amazoncognito.com/login?client_id=MYCLIENTID&redirect_uri=http://localhost&response_type=code
User sends a POST request to the TOKEN endpoint (/oauth2/token) with the following parameters
POST https://hocublen.auth.eu-west-1.amazoncognito.com/oauth2/token
Content-Type='application/x-www-form-urlencoded'
grant_type:authorization_code&
client_id:<MYCLIENTID>&
redirect_uri:http://localhost&
code:<CODE_FROM_LOGIN>
Where <CODE_FROM_LOGIN> is the code returned by /login endpoint on the first step.
My problem is that the first endpoint (/login) works fine and I get the code, but the second endpoint always returns a Bad Request response with an "invalid client" message.
Is there something that can be missing from the configuration?
Also, if I choose to ask for a token from the login endpoint instead of a code, is this token equivalent with that of the TOKEN endpoint?
It seems that when one creates an AppClient the "Generate client secret" is enabled by default, but in subsequent views of the AppClient, one has to press show details to see that the password is set and what the password is.
For the scope of my needs, I just removed the password.
Invalid client is occured when you're generating client_secret for your app clients. You should add your client_secret in your request.
I'm unable to authenticate / sign-in via AzureAD when running testCafe.
const testrole = Role(
'https://login.microsoftonline.com/',
async t => {
await t
.typeText(Selector('input').withAttribute('type', 'email'), *******)
.click(Selector('#idSIButton9'))
.typeText(Selector('input').withAttribute('type', 'password'), ********)
.click(Selector('#idSIButton9'));
},
{ preserveUrl: true }
);
The above steps work fine, however after entering the password I get a message saying:
"Unable to sign in to Outlook account, Error: AADSTS900561: The endpoint only accepts POST requests. Received a GET request."
From my initial search, it seems like something to do with 3rd party cookies on the browser. However, I'm unable to find a solution at this time.
Any idea how I get around this issue?
The Azure AD product team has always reminded me that it is a bad idea to try to automate sign in like that.
They will probably detect that you are a bot and start blocking your requests, even if you succeed.
Instead, to acquire access tokens you need to use either the client credentials flow (for app-only tokens) or the resource owner password credentials flow (for delegated user tokens).
Client credentials flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
ROPC flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
You have to take good care to secure the credentials used for testing.
And use a test tenant if possible.
I'm trying to acquire a 2 legged oauth2 access token for google's storage api through a service account.
The relevant documentation is contained here:
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
I first tried attempted to acquire the token through their HTTP/REST api. I eventually gave up being unable to get past a 400 response with the following details:
{ "error" : "invalid_grant" }
I then turned to the recommended method: using the java Google api client library (I'm using scala).
val credentialBuilder = new GoogleCredential.Builder()
.setTransport(GoogleNetHttpTransport.newTrustedTransport())
.setJsonFactory(JacksonFactory.getDefaultInstance())
.setServiceAccountId(Configuration.GoogleAPI.ServiceAccount.email)
.setServiceAccountPrivateKeyFromP12File(new File(Configuration.GoogleAPI.ServiceAccount.pkcs12))
.setServiceAccountScopes(Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL))
def updateToken = {
val credential = credentialBuilder.build()
credential.refreshToken()
// ... do stuff here with token
}
Running the above, I get a TokenResponseException, with a payload identical to the error I was getting directly accessing the REST api. 400 Bad Request, invalid_grant error.
Doing some research (on both stackoverflow and elsewhere), I find that the most common reasons for this error message are:
1) The local clock is not synced with Google's servers. I suspected this even back when I was using the REST api because I've encountered this issue for other services before. I'm fairly sure its not a clock issue however, because I have repeatedly synced my clocks with an external ntp server:
sudo ntpdate -s ntp.ubuntu.com
2) The other common cause for this error is setting the service account client ID incorrectly. Most people set it to their service account client id (ending with "apps.googleusercontent.com") instead of their service account client email. Its pretty clear that this isn't the problem, since I'm correctly pointing to the email (the docs instructed this, so I followed the directions), ending with "#developer.gserviceaccount.com".
I'm stuck. I've checked the user documentation, the javadocs, various forums. The error message isn't very helpful (probably designed that way, since it's a security endpoint).
What other possible causes for this error exist? What can I do to get my service account access token?
If you are using OAuth2.0 to access a google analytics account then there could be one more reason of getting invalid_grant. As per developer docs:
If the application attempts to use an invalidated refresh token, an
invalid_grant error response is returned. The limit for each unique
pair of OAuth 2.0 client and Google Analytics account is 25 refresh
tokens (note that this limit is subject to change). If the application
continues to request refresh tokens for the same Client/Account pair,
once the 26th token is issued, the 1st refresh token that was
previously issued will become invalid. The 27th requested refresh
token would invalidate the 2nd previously issued token and so on.
INFO: com.google.api.client.auth.oauth2.TokenResponseException: 400 OK
{
"error" : "invalid_grant"
}
my code is
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(js)
.setServiceAccountId(emailId)
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(new File(privateKeyPath)).build();
System.out.println("SERVICE ACCOUNT SERVLET CALLED");
credential.refreshToken();
this method is running fine but suddenly it starts to give error.
Possible reasons:
1) I was having a similar problem caused by the time on my server being incorrect. Make sure your system clock is synchronized.
2) You should reuse the access token you get after the first successful authentication. You will get an invalid_grant error if your previous token has not expired yet. Cache it somewhere so you can reuse it.
3) Make sure that you pass the access token, and not refresh token as that fails. When you run, it turns the OAUth2 refresh token into an access token and passes that to the service. If you pass the raw refresh token, this is not acceptable for API access without turning it into a short-lived access token.
4) You might have reached the refresh token limit. Certain Google APIs have this, some explanation you can find here: https://developers.google.com/compute/docs/authentication
5) You also can revoke it. Go to your Google API Console ( https://code.google.com/apis/console/ ) and revoke your Client Secret under Client ID for installed applications. Be sure to also update your code with the new Client Secret