I have an Ionic 2 app that works as a native app and as a progressive web app hosted on an Azure Web Site (which is not the same site as my API App Service Site). On the mobile side, I can get refresh tokens successfully by using the mobile SDK's login method and the making the REST call. However on the web side (PWA), I can't use the SDK to login because InAppBrowser won't work because login.microsoftonline.com sets X-Frame-Options to DENY. Therefore, I redirect the browser to /.auth/login/aad?session_mode=token&post_login_redirect_url= with a redirect URL coming back to my PWA index page. That sends me the token back via #token which I am able to parse and use to successfully authenticate to my back-end API.
What doesn't work for me is calling /.auth/refresh. That always gives me the error:
The refresh request issued by sid... failed because no refresh tokens
were found in the token store.
The API App is configured to return an access token for graph.microsoft.com and I can see the refresh token in an initial call to /.auth/me. I can also login directly via a browser session using /.auth/login/aad and no parameters. There I can call /.auth/me and /.auth/refresh successfully
So what I am trying to figure out is how to make this work in the browser. I need the user to get redirected back to my app so I specify the post_login_redirect_url parameter. With that the user gets logged in successfully and redirected to my app. However, that is when the call to /.auth/refresh fails with the error above. I am hoping this is just a matter of not passing the right parameters to the login endpoint but I am not sure.
Related
I'm hosting a web application built with NestJs and React (NodeJs) in an IIS Server with IIS Node. To secure my app, I'm using a system with JWT Token + Refresh Token and Windows Authentication to automatically get the connected user and so generate tokens.
Everything (almost) is working fine, but I have a problem with the Windows Authentification. Each time the JWT Token of my application expired (so the API returns a 401 error page) and only after a refresh of the navigator page, the navigator prompt again the pop up to set windows credentials. The logic use case on this is that one day you're using the webapp, and some days later you want to use the app again, but your token is expired, 401 error, windows credentials is prompting.
If the token expires, and the user simply navigate to another page (so no page refresh with my React SPA) there's no problem, the JWT token is refreshed with the refresh token thanks to the API.
I've already tried some stuff:
Disable Loopback Check
Enable Anonymous and Windows Authentication
Changing some random settings
But I haven't found a solution yet.
My goal is to only have the Windows Credentials display once, when the user visits the page for the first time.
As I'm out of ideas, I'm considering setting a JWT that never expire, but of course it's not a great solution.
Thank you very much for your help!
I ended up using a custom 4xx code to handle my 401. So if my API is sending me a 499 http, I know it mean for my frontend that the session is expired. Hence, I don't have the prompt for Windows Credentials.
I have deployed an azure app to azure app service. It has no frontend part, simply an API app that does some http calls.
I have configured the Authentication/Authorization section to log anonymous requests using Azure AD.
I have registered the app in AD and connected everything together.
Here is the problem:
Upon first sign in, everything works great, I sign in and the jwt token is sent to my app and I can parse it.
However if I am already signed in and go to my app again a jwt token is not sent. However doing a GET request to /.auth/me simply returns [].
If I send a request to /.auth/refresh I get a 403 forbidden.
A bit stuck on how to proceed here. Thanks.
What is the status of your Action to take when request is not authenticated? Is it Allow anonymous or Sign-in with Azure AD?
If it is the former (allow anonymous), what you observe is expected behavior.
If it the latter - it is not expected.
When you set to "Allow anonymous" you instruct to not do anything if request is not authenticated. So, nothing happens, and you do not see any token. If you configure to "Login with ...", you will be automatically redirected if you are not authenticated.
UPDATE
Can you define "If I am already signed in.."? Also, if you configured to not allow anonymous request, every request hitting your application code will be authenticated. The app service authentication module takes care of intercepting unauthenticated calls and redirects them. Additionally /.auth/me endpoint will redirect to sign-in all unauthenticated calls, but /.auth/refresh will not.
You may also want to enable token store, which is enabled by default. The option is located directly under the list with authentication providers.
You can find more information about authentication and authorization in Azure App Service here:
https://learn.microsoft.com/en-us/azure/app-service/app-service-authentication-how-to - check out the sections access user claims, retrieve tokens in app code and refresh identity provider token
I have separate UI web app from the API web app. Both registered as applications in B2C. I've enabled Azure App Service Authentication / Authorization (easy auth) on the UI web app, and configured the API web app to use JwtBearer middleware to authenticate calls to API.
This seems to work, but I have trouble getting scopes through to the API web app. I have published the scopes in the API app, and configured the UI app to have access to these scopes.
I've tried different login URL options, e.g., https://myUIapp.azurewebsites.net/.auth/login/aad?p=b2c_1a_mysigninpolicy&scope=openid+https://myb2ctenant.onmicrosoft.com/api/company.read&post_login_redirect_uri=/app
and ensured that the API apps "App ID URI" (in B2C app settings) is indeed "api", while the scope name is company.read. Still after successful authentication, when going to /.auth/me, I do not see the scope, I do see other claims just fine.
Where should I start looking into pointers on this?
UPDATE
I've determined how I end up in this situation, but it is still unclear why:
User authenticates starting with URL such as: https://login.microsoftonline.com/mydevb2c.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1A_signin&client_id=UIAPP_GUID&nonce=defaultNonce&redirect_uri=https%3A%2F%2FUIAPP.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback&scope=openid%20https%3A%2F%2Fmydevb2c.onmicrosoft.com%2Fapi%2Fcompany.write%20https%3A%2F%2Fmydevb2c.onmicrosoft.com%2Fapi%2Fcompany.read&response_type=id_token%20token&prompt=login
After successful authentication, user is redirected to https://UIAPP.azurewebsites.net/.auth/login/aad/callback, as defined, BUT is immediately redirected back to authentication system with default scope set "openid+profile+email", i.e. URL such as https://login.microsoftonline.com/mydevb2c.onmicrosoft.com/oauth2/v2.0/authorize?response_type=id_token&redirect_uri=https%3A%2F%2FUIAPP.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback&client_id=UIAPP_GUID&scope=openid+profile+email&response_mode=form_post&p=b2c_1a_signinsuomifi&nonce=somenonce&state=redir%3D%252Fapp
If I take the access_token from the first callback to /.auth/login/aad/callback it contains the requested scopes, but second authentication callback obviously doesn't as it requests default scope set.
Do I perhaps need to start the easy auth login process via .auth/login/aad in order for it to accept the callback as well?
UPDATE 2
Yes, need to start the process via .auth/login/aad: when using login URL such as https://myUIapp.azurewebsites.net/.auth/login/aad?p=B2C_1A_signin&redirect_uri=https%3A%2F%2FmyUIapp.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback&scope=openid%20https%3A%2F%2Fmydevb2c.onmicrosoft.com%2Fapi%2Fcompany.write%20https%3A%2F%2Fmydevb2c.onmicrosoft.com%2Fapi%2Fcompany.read&response_type=id_token%20token&prompt=login&post_login_redirect_uri=/app removes the second authentication redirect.
The question now is, why do I only see the id_token in .auth/me and not the access_token that is clearly returned to the .auth/login/aad/callback? And ultimately: how come using the access_token as Bearer token, I still cannot query the easy auth secured API, but get error You do not have permission to view this directory or page.? I have followed steps in Azure client app accessing Azure api secured by AD.
If I switch off easy auth, and use the JwtBearer middleware in my API, it works fine.
I've scoured the api docs, as well as StackOverflow, and I've yet to find the answer to my question. And it is possible I'm misunderstanding how the system works.
Here's the scenario our client wants:
User logs into our website
At which point we authenticate the user in our system, and One Login via the api.
After the user logs into our dashboard, they can click an link and be redirected to their third party analytics app due to the fact that I've created a new session with One Login.
Here are the steps I've completed.
I've successfully received an access token via --> https://developers.onelogin.com/api-docs/1/oauth20-tokens/generate-tokens
I've successfully used the access token to generate a session login token via --> https://developers.onelogin.com/api-docs/1/users/create-session-login-token
I've successfully used the session login token to create a new session.
I'm receiving the proper cookies from One Login after making the create new session request, and - at that point - if I enter the URL onelogin.com/login, I am taken directly to the dashboard.
At this point I know I'm properly authenticated with One Login. However, I'm not sure how to directly access a third party app from a link on our website.
Thanks.
Two ways:
If the app supports SP-initiated SAML, just navigate the user to the application and it'll do the whole SAML flow- App redirects to OneLogin - OL authenticates user (because you have a session) --- redirects SAML to app
Use the launch endpoint - You can create a URL to an app by using this format: https://app.onelogin.com/launch/{app-id}. For example, you can provide a link to an app like this:
Time Reporting
Details on that endpoint can be found here: https://developers.onelogin.com/api-docs/1/embed-apps/get-apps-to-embed-for-a-user
Take note that you're probably going to want to use the optional flag that makes sure to redirect to your login page, not OL's if you've built a login facade.
I'm making web app using node.js express with Restful API.
And, to use my web app, the user must login. If user doesn't login, he always stays in login page.
But, I heard that restful api doesn't use session or cookie information to maintain user login.
So, I heard that it use JWT. So, I want to use this. But, I saw that it has to compare token information when user access Restful API.
Then, in my case, should the user always have to request token information to the web app server to use my web service? (I mean add token in request header when user request every page)
you can use
HTML Local Storage
When you get JWT token save some value at local storage localStorage.setItem("logenin", "yes");
and check at every page or where you need this infomation localStorage.getItem("logenin");