Coder Social home page Coder Social logo

Comments (22)

mmzoo avatar mmzoo commented on August 28, 2024 1

I like the block approach! I need to configure the expiration time per consumer (infinite expiry for iphone and 2 hours for web), so this approach would solve my problem, too.

from doorkeeper.

nessamurmur avatar nessamurmur commented on August 28, 2024 1

So - I want some kind of dynamic configuration to override the determination of the expiration time in run time (like Facebook's offline_access), which then supports 0 or some kind of special value to mean "never expires". What do you think?

@miyagawa Please do not implement a feature like that with no expiration time. Expiring access tokens is a security feature... Not expiring them opens applications to attack. In mobile apps most of all since the access token is actually user accessible and not passed on back channels between two web servers.

Instead you may want to investigate implementing an offline_access feature via a scope. If a client has that scope it should be able to request a new access token with a refresh token even if the user doesn't have a current session.

You may also want to look at the OpenIDConnect Spec and in particular the section on Offline Access.

from doorkeeper.

mmzoo avatar mmzoo commented on August 28, 2024 1

Can we open this issue again?

I need different expiration times for different resource owners or applications, say 10 hours for admins and 2 hours for normal users, just as @felipeelias demonstrated.

Please do not implement a feature like that with no expiration time.

This issue is, in my eyes, not primarily concerned with unlimited expiration time. I agree that that would not be good.

However, the block approach would allow for different expiration times for different users and/or applications rather than one for all. I can e.g. imagine the user checking a checkbox at login saying "This is a public computer, my token should only be valid 10 minutes just for this session" or something like that.

Or, say, 1 hour on mobile devices but 10 hours on desktop clients.

from doorkeeper.

nessamurmur avatar nessamurmur commented on August 28, 2024 1

@mmzoo Are you trying to use access tokens for session management? I urge you to please not.

Since access tokens should only be used to determine if a client application has authorization to act on the user's behalf it shouldn't matter how short the access tokens live. The client application can (and should) refresh their access token as needed to continue their authorization to user data (if the provider can determine the user still gives their consent).

Whether or not the user has a session is up to the client to determine. That maybe using by using an access token to get some data back from the provider or another service. But the token itself shouldn't be an indicator of having a session. IMHO, anything more than about 10 minutes is an irresponsible amount of time to let an access token be considered valid. According to section 5 of the OAuth 2 spec, access tokens should live < 1 hr.

Issue short-lived bearer tokens:  Token servers SHOULD issue
      short-lived (one hour or less) bearer tokens, particularly when
      issuing tokens to clients that run within a web browser or other
      environments where information leakage may occur.  Using
      short-lived bearer tokens can reduce the impact of them being
      leaked.

I need different expiration times for different resource owners or applications, say 10 hours for admins and 2 hours for normal users

Can you talk some about your specific use case? There's probably another way to tackle the same thing that doesn't not involve leaving user data open to unauthorized access.

from doorkeeper.

nessamurmur avatar nessamurmur commented on August 28, 2024 1

@mmzoo Do you have an email I can send a response to? I have some ideas and suggestions from what I've built in the past to handle use cases like auto sign in, auto sign out, handling access tokens when a user changes credentials, knowing about session across applications, etc. I've built and thought about all of it before and would love to discuss with you but hate to fill this issue with our implementation details.

Some brief details:

Option 1: Shared data store
I know there was an assumption that this is not the case, but if it's a possibility and all the clients will be behind a firewall it may make sense... This won't help if a 3rd party app or a mobile app needs to know about the session, but it's an option. I haven't gone with this option in the past for those very reasons so I'm not confident I can think out all the pros and cons but some are apparent (having to be behind the firewall, availability of the data store, etc.)

Option 2: Session state

One generic suggestion would be to have the provider calculate an opaque session_state value that is sent to the client along with the user's information. This session_state would be recalculated every time there's a change to their session's status. The client can hit an endpoint sending the session_state it knows about to the server and the server can respond with whether or not the state is still valid. If it's not valid the client can end the user's session and perform another handshake with the server to determine whether or not the user is currently signed in. How you store it, when you send it to the provider to determine the session status, etc. is kind of out of scope and hard for me to advise you in with out more intimate knowledge of your specific use case and needs... But generically, that's one way to do it. As far as making sure the client app I authorized to that information, you could do something like the client credentials flow.

There's even more ideas in the OpenID Connect Session Management spec. OpenID Connect is primarily an identity layer on top of OAuth 2 but there's also some good ideas in there for how to handle different use cases like yours.

from doorkeeper.

mattgreen avatar mattgreen commented on August 28, 2024

I'm looking for this feature as well.

Doorkeeper devs, if I submitted a pull for this feature with accompanying specs, would you be open to accepting it?

from doorkeeper.

felipeelias avatar felipeelias commented on August 28, 2024

@mattgreen we'll be open to accept it :-)

@miyagawa we thought about it, we just didn't implement because of the specs, but it is very requested feature.

I think some dynamic configuration would help. Maybe we should use the same idea of #70? This way you could configure the expiration depending on resource owner/client/scope or others.

Thoughts?

from doorkeeper.

mattgreen avatar mattgreen commented on August 28, 2024

What if we used a config block, much like resource_owner_authenticator? I can imagine the block accepting two parameters: the resource_owner, as well as the token. Additionally, perhaps it could be used to signal that a token should not be issued; say, by raising a specific exception.

By doing this, you could enforce odd requirements, such as "only one access token issued per x days", etc. It's tricky to know where to draw the line in terms of a sane level of configuration.

from doorkeeper.

felipeelias avatar felipeelias commented on August 28, 2024

@mattgreen not sure if this would be the exact place to handle the case for "only one access token issued per x days". I like the idea though.

This will be something like a decision of the expiration time based on some parameters, few use cases:

  • If the request has a specific scope, like offline_access, then return nil as expiration time
  • If the client (or resource owner) has an specific attribute or permission (maybe "admin" client)

So we could use a block like:

access_token_expiration do |client, resource_owner, request|
  if request.scopes.include? :offline_access
    nil
  elsif client.admin?
    10.hours
  else
    2.hours
  end
end

# and then, during token creation
Doorkeeper.configuration.access_token_expiration.call(client, resource_owner, self)
# => 2.hours (for example

Not sure if this would be the best way to handle this, I'd love to hear some thoughs.

from doorkeeper.

felipeelias avatar felipeelias commented on August 28, 2024

Just started an experimental configuration for this on this branch: https://github.com/applicake/doorkeeper/compare/dynamic-expiration

from doorkeeper.

bryanrite avatar bryanrite commented on August 28, 2024

πŸ‘ for the block approach as well.

from doorkeeper.

luxerama avatar luxerama commented on August 28, 2024

This is exactly what I am looking for. Is there anything I can do to help?

from doorkeeper.

ksheurs avatar ksheurs commented on August 28, 2024

was something like this ever implemented?

from doorkeeper.

miyagawa avatar miyagawa commented on August 28, 2024

My use case was specifically web apps as client where credentials can be
saved securely. Anyway I stopped using doorkeeper at this point.

from doorkeeper.

tute avatar tute commented on August 28, 2024

Default expiration time can be configured in

option :access_token_expires_in, default: 7200
. Accepts values in seconds (default is two hours), so 10 years is around 315.360.000 seconds. Thanks for your input!

from doorkeeper.

mmzoo avatar mmzoo commented on August 28, 2024

@niftyn8 I appreciate your commitment very much, thank you :) Yes, I seek to implement a single-sign-on architecture with "server side session authentication" and found that, if I were to build that from scratch, it would look like OAuth.

My use case

I have the client applications alpha.dev and beta.dev etc. and the doorkeeper server doorkeeper.dev.

My goals are
  • The end user can seamlessly switch between alpha and beta without having to log in twice
  • The end user can logout of all client applications with one click
  • The end user has an overview of all ongoing sessions, just like Github has in your account settings, and can remotely invalidate them
A few conditions/assumptions are given
  • I have full control over every application (except, say native mobile client apps where secrets and traffic can be forcibly extracted)
  • All traffic is TLS encrypted
  • There is no shared data store, if any application wants to talk to another, it has to be via API requests
  • Every client app is a separate OAuth Doorkeeper consumer, that is, a token of one app cannot be abused for another app
My suggested solution is
  • When logged in in alpha, there is some form of unique token in the local cookie
  • At every request (or, at least rather frequently), I let alpha validate that token against the list of sessions at doorkeeper.dev (say, via requests signed with that token to avoid actually sending the token over the wire again and again)
  • With that request to doorkeeper.dev I can also update the latest session activity and retrieve the current set of authorization rules for that user
My thoughts are
  • The Doorkeeper gem basically already provides that architecture
  • Everybody says OAuth access tokens should be short-lived to prevent misuse of leaked tokens (and I agree), but is a cookie not a long-lived shared secret as well? I guess it's not passed around that much though...
  • Heroku solves this via a cross-subdomain cookie, but I don't have the same TLD so I cannot do that
  • Github can maintain the sessions sever-side because there is (AFAIK) just one application, not alpha and beta like in my case

access tokens should only be used to determine if a client application has authorization to act on the user's behalf

This is true. But let's take the simple example of the user changing the password (which only the server is aware of) because the user feels that it might have been stolen. I want to stop the client application from acting on the user's behalf immediately.

The client application can (and should) refresh their access token as needed to continue their authorization to user data

So you want me to ensure some sort of access token rotation by using refresh tokens? I just felt a little awkward sending refresh tokens over the wire basically all the time. But then again, I see your point. If someone steels my cookie it would only be valid for a very short time.

If that's all then I can implement that! :) It would cost me an additional round-trip though in case the access token timed out. I don't feel it's ideal that that could happen at every request, but I could live with it if it's more secure.

Whether or not the user has a session is up to the client to determine

Yes, but in the case of SSO it should be up to the server, not the client.

But the token itself shouldn't be an indicator of having a session

I thought this was a practical thing to do in my use case. Actually, I believe that having some sort of shared token between the client and the server is the only way to implement this. May it be either a rolling token or a long-lived one.

But, to summarize: The major problem you see is that leaking a token gives evil people access for too long time? What if I roll the token every minute using a refresh token? And would it not be even more secure to never send tokens over the wire by just signing the requests instead of sending the actual tokens? I could keep a separate, public session identifier around so that the server knows which access token to validate the signature against...

from doorkeeper.

ksheurs avatar ksheurs commented on August 28, 2024

@niftyn8 @mmzoo would love if you guys could loop me in as well (ksheurs at gmail). i've been looking to build something very similar. thank you!

from doorkeeper.

mmzoo avatar mmzoo commented on August 28, 2024

@niftyn8 Brilliant. My thoughts were actually progressing into exactly that direction (session state) but you were some steps ahead of me :) I was just creating a sessions table in my doorkeeper app to keep track of those...

You can reach me via sso🎩posteo.ee so we don't have to spam this thread :)

Thank you doorkeeper.

from doorkeeper.

tute avatar tute commented on August 28, 2024

This is a great discussion guys, please move on in a Github issue/wiki instead of on private email! πŸ‘

from doorkeeper.

mmzoo avatar mmzoo commented on August 28, 2024

It turned out that the discussion moved around over here for those interested.

from doorkeeper.

tute avatar tute commented on August 28, 2024

Also checkout the projects and talks of @jagthedrummer, he's been doing quite a good job on this (and presenting in conferences). πŸ‘

from doorkeeper.

jagthedrummer avatar jagthedrummer commented on August 28, 2024

Thanks for the mention, @tute! Here's a link to a bunch of resources for a talk I gave at RailsConf about using doorkeeper for SSO.

UPDATED : I forgot to include the link. 🀦

http://www.octolabs.com/blogs/octoblog/2014/04/22/service-oriented-authentication-railsconf/

from doorkeeper.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.