New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add logout #48
Comments
|
Noted and mentioned here that I'm happy to look at a PR for this |
|
i having this problem too. I need logout =D |
|
Since logout might be provider specific, would it be possible to return the specific configuration? For example, I am using auth0 as my IDP which has an api endpoint for terminating a session. I can easily make the api call outside of this library, but I need the platform specific callback url which this library has available already. If there was an exposed method allowing me to retrieve the configuration, I would be able to make a logout call via http. Is this a good possible workaround @MaikuB ? |
|
Regarding getting the configuration, I don't believe so as this plugin is a wrapper around the native AppAuth SDKs, which doesn't support getting provider specific configuration. It's more aimed for those that follow certain standardised specs. It's also limited by what members are in the native class(es) used to represent the configuration. As Auth0 supports OIDC, you could retrieve the configuration yourself and try making an API call to terminate the session as you suggested. Haven't tried this myself but I would think it should work |
|
Hello @MaikuB, I wanted to share the behaviour that I experienced. Currently, I have a simply flutter project which has a button that sends an AuthorizationRequest and then a TokenRequest. It works fine (tested on Android pixel 3 emulator). The first time I tap the button I get redirected to my login page, I authenticate and then I'm redirected back. So far so good. If I tap the login button again, it does a quick trip but I don't get prompted for login. Makes sense. The behaviour that is confusing me is that if I kill the app and restart it and tap the login button, I'm not being prompted to login. Somehow the tokens were cached somewhere. I understand that the tokens are still valid on my backend but the question is: where is the app caching the information? Is there a way to clear it? Thank you |
It's your browser so you can clear the browser's cache |
|
Hi @MaikuB! Just an idea. May you just add a way to clear the browser's cache? I mean, if we could "reset" the library without making an actual log out, it would be sufficient. In that way, you don't need to know anything about the real environment. |
|
@rocboronat what you're asking for isn't possible as far as i know. Each app essentially runs in a sandboxed environment. I would say it's a security flaw if there was a way to programmatically to manipulate a browser's cache via another app. Also note that this plugin is just a wrapper to another SDK that does all of the work around authentication |
|
For what it's worth I've observed this same behavior (caching of session / token) in the React Native AppAuth wrapper as well. I think it's an inherent issue in the Android/iOS layer with the way the webview is implemented as it shares session information with the system browser. |
|
Hello, iOS For me worked passing But after redirect to login OKTA page i do not know how to close it programatcily. i Need to hit Cancel to close webview/browser. |
|
@codenamics Did you ever solve your issue for iOS? Everything below works on Android, but I cannot for the life of me kill the browser cookies in iOS. I'm using IdentityServer4, and rather than the redirect uri you're passing as a second argument, IdentityServer4 wants a My version of your snippet above looks like this: Maybe this could help you? Also, I tried your solution, but with IdentityServer4 rather than OKTA, my app just crashes (stops) immediately with the following error: This makes sense as my I'm getting pretty desperate to find a solution for this as just "forgetting" the tokens in my app isn't good enough. The browser keeps the auth cookies around, so when logging in again it just automatically uses the cookies and you never get a chance to actually hit the login screen. I'm actually a bit shocked at how difficult this has turned out to be. I'm at a complete loss as to how to kill the browser cookies in iOS, and at this point it's about to hold up my production app release. I've also posted a (slightly) more detailed question here on StackOverflow with no answers yet: Can anyone on this thread help point me in the right direction? This seems like it should be so simple. |
|
the thing is that if you use routes as stated in my code it is JWT not cookies. so when you hit logout route you actuly revoke the token. so you should be logged out. also Try to push/clear screenstack to redirect to login screen |
|
When you call method for authorizing and exchanges code, there is needed to add an additional parameter called "promptValues" with 'login' value. In this way, every time the login is made there is no value in the cache and it always asks for a new login. I came to this solution from this post openid/AppAuth-Android#215 where it was commented about Logout and Delete browser history and OpenId docs |
|
@mgalsina You are an absolute hero. I can't believe I didn't come across this with all of the time I spent troubleshooting. I just tested and it works a charm. I'd still love to know if there's a way to physically end a session for federated logout purposes, but for my use case now, this will work fine. Thank you a thousand times! |
This is how I'm logging out: CHANGE "{TENANT}" to your tenant. This will even close the webview automatically afterwards. Edit: Oof, just saw you're using iOS. Tested on Android only. |
|
@sharpsan Yeah your snippet (essentially) works for me on Android. The IdentityServer4 logout endpoint is called That being said, it does appear that this is somehow working on iOS for @codenamics, though I can't guess why based on all my tests. My only guess is that somehow OKTA is sending valid auth response from its own endsession endpoint, though this makes no sense to me. Shrug |
|
I have it working with both Android and iOS for Azure B2C https://www.detroitdave.dev/2020/04/simple-azure-b2c-flutter.html |
|
@dwhiteddsoft That's a clever use of using the All of the conversations / blog posts / github issues I've seen so far lead me to believe that there is a gaping hole in AppAuth when it comes to logout. Even though every OAuth / OIDC provider I've seen provides a compliant endsession endpoint, the only suggestions I've seen regarding actually calling it require modifying the AppAuth library or writing plugins for it. That or I'm missing something so obvious I should be embarrassed. |
|
The iOS AppAuth SDK supports it from what I know but the Android AppAuth SDK is missing it as it needs a new maintainer (see openid/AppAuth-Android#444). So even though there seems to be a PR for it in Android (https://github.com/openid/AppAuth-Android/pull/525/files), it won't be reviewed merged in unless there's a new maintainer. One possible workaround is as I'm (currently) trying to depend on the official libraries, is to fork this plugin. Within that fork, update the Android dependencies to point to a fork of the Android AppAuth SDK that has logout support. If I'm not mistaken, this can be via JitPack. After that add the necessary code changes to support logout including calls to the iOS API that supposedly already exists |
|
@MaikuB It shouldn't have to be up to you to do that, although I'm sure there are some people (like myself a few days ago) who'd be thankful you did. Android doesn't need it as bad as iOS does. If you read my comment above, the Authorize method can be easily and seamlessly abused to call the That being said, I'm using @mgalsina's solution here and just dropping all of the tokens I'm storing locally. It has the added benefit of not showing the "such and such wants to Sign In using xxxxxx" dialog on iOS during sign out. Essentially the solution is to never allow the browser to store cookies in the first place via the For me this works great as I don't plan on ever implementing federated sign out from my app, though now that I've written this, I'm sure it's destined to be a requirement within the next 30 days :) |
|
I don't care for the UI experience either but I ran into the same thing both of you did. Since this lib uses AppAuth underneath, the delta of steps to get this all working is pretty steep. As I continue on in my Flutter journey this is a great example where the underlying libraries sometimes fail us and I wonder if more Flutter libraries should simply fork underlying libs into themselves and simply build an 'all in one' (allowing a mechanism to plug gaps if needed) instead of just a wrapper on top of a library. |
|
@dwhiteddsoft I highly suggest @mgalsina's solution as it would seem to solve the problem you put forth in your blog post and it has a great UX to boot. For the bigger question of federated signout, it's really something that needs to be fixed in the core AppAuth libraries. Fixes for this don't belong in the Flutter libraries |
|
I've created a pr to help address the iOS side of this problem. With iOS 13 you can now pass There is no equivalent on Android. However as @hallidev mentions here there are easier ways to clear sessions on android including simply opening the LOGOUT endpoint and redirecting back to your application. |
|
Latest version works great for iOS! Any updates on the Android side? If not, can we at least point to the Android AppAuth SDK that has logout support? |
|
As far as I know, Android doesn't support private auth sessions. If you want logout support on either platform, you can fork this repo and have it point to a fork of an AppAuth SDK that has support for logout. In case you haven't been following this thread, the official Android AppAuth SDK doesn't have support for logout as isn't an active maintainer for it |
|
Is there anyone who actually got a fork working where they implemented the end session functionality on iOS by using the API that's provide by the AppAuth iOS SDK? I tried playing around with it but it would show a prompt that the app wants to show the user to sign in and it disappears quickly too. I must be missing something but not sure what as there's a lack of examples |
|
@MaikuB I have only been able to do it with an HTTP request I send manually, instead of using the SDK. |
|
On iOS 13, I'm seeing the authentication session reset when using MFA which backgrounds the app when |
|
Anyone knows what's the difference between flutter_appauth and flutter msal_mobile, and whether it solves this issue? |
|
@mgalsina, do you store the refresh token somewhere in your case so that you can keep your user signed it? and is your solution secure (e.g.: Will the user remain signed in to b2c if we follow such method? I think he shouldn't) |
|
I solved the problem with a trick: |
|
@gabrimatic is your app only targeting Android? Opening a browser on iOS led to issue for me #161 |
|
@MaikuB it looks like the Android PR that you mentioned earlier was merged with the end session support. Is this what was needed or is there something still missing? |
|
@jhoward321 I mentioned earlier in the thread that I couldn't get end session working on iOS. Note that I had put a "help wanted" label on this issue and this is open-source so you can fork the repo, try to get it working and submit a PR |
|
Hello @MaikuB, I have managed to force my flutter iOS app to login as a new session everytime. Also got the revocation of the token running as my logout. Works well! Now the problem: I am authenticating with my IDP via corporate user certificate. On Android the revocation and opening a new session etc works but it seems like the browser caches the certificate and proceeds the login. Even when the certificate is removed from the device the login still works. Is there any possibility to solve this issue. iOS works like expected. for iOS I have used the prompt value login, added Origin Header with Redirect URL as value and the IDP had the possibility to add a CORS Domain. Added Redirect URI therefore there. Now it seems to work. |
|
@MaikuB I have this working on a fork for iOS. That said I had to work around the prompt. I needed to provide a SFSafariViewController Custom User-Agent. Seems to be the only way to make that work. With ASWebAuthenticationSession I get the prompts at login and logout. With preferEphemeralSession endsession doesn't log me out. Would you still be interested in a PR for this? |
|
@ccadieux I don't think a PR will be necessary. I figured out the issue on iOS so I've published a 2.0.0-dev.0 prerelease that adds support for end session requests. I've tried it out with the demo IdentityServer instance and with an Okta server. If the community could given this a spin that would great. Edit: a prompt will appear will depending on the version of iOS used but this is expected behaviour given the APIs that are meant to be used |
|
My fork is using the deprecated SFSafariViewController because of that prompt. Prompting the user at sign out with a warning that they are going to sign in is not usable in my opinion. I tried 2.0.0-dev.0 and get the following prompt at logout. Are you able to give us the option to use the deprecated SFSafariViewController. This restores the behaviour of no prompts. It's a weird situation but none of the new api's support what we need for this. I would make the default what you have and leave it up to the user to make the decision. With the warning that it may cause issues in the future. |
|
@ccadieux would you submit be able to PR for this to the |
|
Part of the challenge with this ask is that technically the OIDC spec doesn't support "logout". In my opinion, it's way overdue for being addressed. There are a couple of drafts out there but nothing (to my knowledge) that's been finalized. OpenID Connect Session Management 1.0 is on it's 30th draft and is referenced in the OIDC core spec as an implementer's guide. In addition, there are a few other draft proposals out there:
All of these provide some possible ways to handle it, but it's ultimately just way too provider specific to solve in a plugin like this. Some providers provide an So, why is this?We need to explore some of the reasons OIDC exists to answer that... OIDC is not intended handle 'sessions'Or, more simply, You don't own the session. One of the purposes of OIDC was to get away from the traditional AuthZ session concept so that native apps could more easily manage authentication. It's about separation of duties and, ultimately, federation. The Idp is responsible for their session and then each client is responsible for their "session". If you really think about it, what y'all are talking about is wanting to be able to terminate the Idp's session, which, is kind of crazy! I know, you are all thinking "this guy is nuts, what is he talking about?!" and that is because most of you are dealing with situations where the client/RP/Idp are all the same company so it becomes really easy to forget about the division that is "supposed" to exist there. Let's talk about FacebookTo help explain this further, think about it in the context of using Facebook. If you are using a bare-bones, pure OIDC, implementation and only offer 'Login with Facebook' in your app (I've seen apps like this in the wild!) then what you're essentially proposing is having a button in your app that logs the user out from Facebook. We all know FB would never allow that! They would say, "you can revoke access and kill your tokens, but you can't manage the FB session." And, that's precisely why there isn't really a 'logout' concept in OIDC -- you're supposed to be revoking access per client. Ok, but that's stupid...But is it? One of the perks of OIDC is the ability to consume a pre-existing 'session' and reduce the number of times someone has to login. Isn't it super convenient when you can click on 'Login' and not have to actually do anything? That's because the Idp 'session' has been abstracted and is pretty much what federation is all about. Right, but, that doesn't really work in the real world...Totally agree and this is why the idea of 'Single Logout' (SLO) is gaining momentum and also why logout continues to be incredibly provider specific and not standardized. However, most providers have APIs for session management and that's where I see SLO starting to head. To me, it would make total sense to expose a 'SLO' endpoint that does NOT require opening a browser. In reality, the browser should be validating the 'session' held by the cookie anyway so, if you terminate the session via API, it should effectively kill the cookie the next time someone tries to use it. It could be exposed via the The big question then...SO WHAT? |
|
@eatplaysleep Perhaps you missed reading this post above? #48 (comment) |
I saw it. I'm not a fan of the UX for that method though. Would still be in favor of a implementing revoke until a better mechanism is made available in AppAuth itself. |
|
Said UX is from the end session request that you mentioned |
|
@ccadieux did you ever end up submitting a PR? I vaguely remember seeing a branch added to the repository but don't know how it ended up there so I've deleted it. Don't remember if it was from you or not as it seemed strange that someone else could've push their own branch here so I didn't take much note of it |
|
FYI I've published 2.0.0-dev.6 that should fix an issue where choosing the cancel when prompted by the dialog that appears on an end session request would prevent subsequent requests from working. If I could get help from others here to confirm that it works and that I haven't broken other flows (as I've applied a similar code change to other places) that they would be much appreciated. I didn't find any issues in my own testing but be good to get more feedback on this |

Currently there is no way to end an active session via this library.
The text was updated successfully, but these errors were encountered: