How to implement OIDC using vuex-oidc in vue.js - vue.js

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.

Related

Cognito AUTHORIZATION endpoint responsds with invalid client

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.

Skype For Business Online Authentication Error - 403 Permission Denied

Hello Microsoft/Azure/Skype experts,
I'm tasked with accessing presence data from Skype For Business Online accounts from my macOS app (native).
I'm unfortunately stuck and i always get a 403 error when i access the autodiscover request and never get the link to the applications resource
I have been following this documentation
https://learn.microsoft.com/en-us/skype-sdk/ucwa/authenticationusingazuread
STEP 1
We have registered the app in the Azure Management Portal using our Office 365 account credentials.
We have used custome redirect URL (http://localhost)
Allow Implicit Flow is set to true in manifest
We pre-configure the permissions needed for Skype for business
online
STEP 2
Issuing a GET as specified in the documentation to initiate sign in and authorization check.
GET https://login.microsoftonline.com/common/oauth2/authorize?response_type=token&client_id=c#####-4d41-485e-871f-0a22aa79e52b&redirect_uri=http://localhost
This returns a 200 OK.
STEP 3
We got the Auto discover URL as described in the documentation.
This is what i get - i use the domain marked in RED.
STEP 4
As per the documentation, they ask me to do this
Requesting an access token using implicit grant flow
So i issue a GET as described
https://login.microsoftonline.com/oauth2/authorize?
response_type=id_token &client_id=######-4d41-485e-871f-0a22aa79e52b
&redirect_uri=http://localhost
&state=8f0f4eff-360f-4c50-acf0-99cf8174a58b
&resource=https://webdirin1.online.lync.com
Now this shows the sign in page, i sign in and then it throws an error
AADSTS90014%3a+The+required+field+%27nonce%27+is+missing.
I researched and could not fix this error.
So after lots of research and looking at this Microsoft documentation LINK (https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#requesting-individual-user-consent) , apparently there is another way of getting the bearer token.
STEP 4 - SECOND TRY
I then Request individual user consent by sending the SCOPE parameter for Skype for Business.
I then issue a GET request to
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=#######-4d41-485e-871f-0a22aa79e52b&response_type=code&redirect_uri=http://localhost&response_mode=query&scope=https://api.skypeforbusiness.com/User.ReadWrite&state=12345
This returns an access code which i use in next step to get the TOKEN
STEP 5 - Get the bearer TOKEN
Issue a POST to following URL
https://login.microsoftonline.com/common/oauth2/v2.0/token With the
following data in POST body
"grant_type": "authorization_code", "client_id":
"######-4d41-485e-871f-0a22aa79e52b", "scope":
"https://api.skypeforbusiness.com/User.ReadWrite", "code":
"OAQABAAIAAACEfexX.........", "redirect_uri": "https://localhost"
This returns the bearer token in the following response JSON
{
"access_token" = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1........w4b-- gnWG_iOGtQ";
"expires_in" = 3599;
"ext_expires_in" = 3599;
scope = "https://api.skypeforbusiness.com/User.ReadWrite";
"token_type" = Bearer;
}
STEP 6
Yay! Got the bearer token at laaast!
Now back to the main documentation
https://learn.microsoft.com/en-us/skype-sdk/ucwa/authenticationusingazuread
And where we do this - 'Resending an autodiscovery request with the bearer token'
We execute a GET request to
https://webdirin1.online.lync.com/Autodiscover/AutodiscoverService.svc/root/oauth/user
Now this, as per the documentation should return this JSON
{
"_links":{
"self":
{"href":"https://webdirX.online.lync.com/Autodiscover/AutodiscoverService.svc/root/user"},
"applications":
{"href":"https://webpoolXY.infra.lync.com/ucwa/oauth/v1/applications"}
}
}
BUT i GET A 403: PERMISSIONS denied error
<div class="content-container"><fieldset>
<h2>403 - Forbidden: Access is denied.</h2>
<h3>You do not have permission to view this directory or page
using the credentials that you supplied.</h3>
</fieldset></div>
So thus i have never got the applications url and I have checked the manifest, registration and i have no idea, why i get this error.
Any inputs would be appreciated.
For step 4, you need to specify nonce=somestring in the URL. Typically this should be a securely random value that is only used once. It can contain any value.
Also, you are only requesting an id token. Set response_type=id_token+token.

Server Timeout when Requesting Office 365 Government Authentication Token using ADAL

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?

Can I auto login a user on the client that has already been authorized on the server?

I have an application that uses google's oauth system to authorize with youtube's api. The code for this is done on our server and we receive tokens without any problem. We'd like to move some of the api calls to the client using their javascript api.
Since we've already authorized the user with the correct scopes required for the youtube api (https://www.googleapis.com/auth/youtube) I assumed when I called authorize on the client it would know that my application was already authorized and allow auto login. Instead I receive a "immediate_failed" response. Does anyone know why? Thanks!
gapi.auth.authorize({
client_id: OAUTH2_CLIENT_ID,
scope: OAUTH2_SCOPES,
immediate: true
}, handleAuthResult);
If you have the token, you can just use setToken instead of going through OAuth2 again.

Google Drive API accessing both "online" and "offline" at the same time

This is a follow up to my previous question: How do I access Google Drive Application Data from a remote server?
I have an application which needs to access Google Drive AppFolder both client-side (online, JavaScript) and server-side (offline, Python). My application is unique in that the client and the server may not be able to communicate past the original authentication.
Thus, I use the following to obtain an auth token for the server (initiated client-side):
gapi.auth.authorize({
'client_id': CLIENT_ID,
'scope': SCOPES,
'access_type': 'offline',
'response_type': 'code',
'state': 'my_state',
}, null, 2),
'redirect_uri': 'http://server/oauth2callback',
'immediate': false
},
handleOfflineAuthResult);
the server stores the credentials including refresh token.
Then the client (in a subsequent user session) sends requests directly to Google Drive for token:
gapi.auth.authorize({
'client_id': CLIENT_ID,
'scope': SCOPES,
'immediate': true
}, handleAuthResult);
now when the client does that it gets a refresh token but invalidates the refresh_token for the server. Thus my server can no longer refresh its token and gets 'AccessTokenRefreshError: invalid_grant'.
Is there any way to solve this problem assuming the client and the server cannot communicate past the original authentication (i.e. the client can't just ask the server for its auth_token, that's by design) ?
The only "solution" I have thought of is to have the client store its auth_token and refresh_token in the AppFolder and the server continuously pull the AppFolder for new credentials, subsequently replacing its copy with the client one.
You say
when the client does that [calls gapi.auth.authorize] it gets a refresh token but invalidates the
refresh_token for the server
At least the first part is incorrect, and I suspect the second part is too. gapi.auth.authorize returns an access token, not a refresh token (see https://developers.google.com/api-client-library/javascript/reference/referencedocs#OAuth20TokenObject).
I doubt very much that requesting an access token for your client is invalidating a refresh token for your server. If you are 100% sure that it is, you should use a separate client ID for each of your JS and web client apps. Note that a JS client will never use a refresh token, as this would be a major security flaw. JS clients always request access tokens as needed, either from your server or from Google.