RememberMeManager in Database

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

RememberMeManager in Database

raupach
Hi there,

has anyone worked on a RememberMeManager that stores the the credentials in the database?

As far as I can tell the current CookieRememberMeManager encrypts the principal and store the encrypted value in a cookie. Identity is restored if we can decrypt the supplied cookie value from the user agent.

Would it be possible to offload this to a database? Say the cookie value is just a nonce. A uuid for example. The RememberMeManager implementation must then look into the database for the nonce. If there is a matching principal it returns a successful identity. Otherwise it doesn’t.

This way we could invalidate remembered sessions for some users and not for all by means of changing the cipher key.

Does this make sense? Could this work?

Any ideas would be appreciated.

kind regards
Björn
Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

Brian Demers
Sounds like that could work.  As for invalidating a single remembered me session, I don't think you would need to deal with an individual cipher, simply deleting the user's key from your database would do it (as the next request would fail to lookup the rememberMe key).

You may also need to heavily depend on caching, as each request might require a DB lookup (but that is up to you and your usage patterns)

Keep us posted!
-Brian


On Tue, Jan 9, 2018 at 10:02 AM, Björn Raupach <[hidden email]> wrote:
Hi there,

has anyone worked on a RememberMeManager that stores the the credentials in the database?

As far as I can tell the current CookieRememberMeManager encrypts the principal and store the encrypted value in a cookie. Identity is restored if we can decrypt the supplied cookie value from the user agent.

Would it be possible to offload this to a database? Say the cookie value is just a nonce. A uuid for example. The RememberMeManager implementation must then look into the database for the nonce. If there is a matching principal it returns a successful identity. Otherwise it doesn’t.

This way we could invalidate remembered sessions for some users and not for all by means of changing the cipher key.

Does this make sense? Could this work?

Any ideas would be appreciated.

kind regards
Björn

Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

raupach
Hi Brian,

On 9. Jan 2018, at 20:20, Brian Demers <[hidden email]> wrote:

Sounds like that could work.  As for invalidating a single remembered me session, I don't think you would need to deal with an individual cipher, simply deleting the user's key from your database would do it (as the next request would fail to lookup the rememberMe key).


AbstractRememberMeManager already assumes using a cipher. CookieRememberMeManager inherits this. What do you think: make a new class and inherit from CookieRememberMeManager and override the unneeded stuff or create a new class, implement RememberMeManager and duplicate code from CookieRememberMeManager?

You may also need to heavily depend on caching, as each request might require a DB lookup (but that is up to you and your usage patterns)

true, we already use permission, so every request already hits the database. Compared to everything else that is going for loading a web page this single statement is neglectable. I don’t expect another query for rememberMe to cause much issue. But agreed, this really depends on individual usage patterns. Might work for some, not for everyone. 


Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 

-Brian


On Tue, Jan 9, 2018 at 10:02 AM, Björn Raupach <[hidden email]> wrote:
Hi there,

has anyone worked on a RememberMeManager that stores the the credentials in the database?

As far as I can tell the current CookieRememberMeManager encrypts the principal and store the encrypted value in a cookie. Identity is restored if we can decrypt the supplied cookie value from the user agent.

Would it be possible to offload this to a database? Say the cookie value is just a nonce. A uuid for example. The RememberMeManager implementation must then look into the database for the nonce. If there is a matching principal it returns a successful identity. Otherwise it doesn’t.

This way we could invalidate remembered sessions for some users and not for all by means of changing the cipher key.

Does this make sense? Could this work?

Any ideas would be appreciated.

kind regards
Björn


Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

Brian Demers
Probably an override, you will still need to add the cookie, so you should be able to override just what you need.



Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 
 
Cool!
Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

Rob Young
I'd be interested to see this in action, I'd be happy to check out what you get up to!

On Wed, Jan 10, 2018 at 10:25 AM, Brian Demers <[hidden email]> wrote:
Probably an override, you will still need to add the cookie, so you should be able to override just what you need.



Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 
 
Cool!



--
Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

raupach
Not sure where to talk about the proposed feature. JIRA Ticket? Mailing list or GitHub issue/pull request?

Anyways here is the link to the implementation: https://github.com/raupachz/shiro/tree/dbcookies The class is called DatabaseRememberMeCookieManager.java

This is more or less a simple proof of concept, so we have something to talk about.I am also not very familiar with the internals of Shiro and the terminology. So please correct me.

DatabaseRememberMeCookieManager inherits RememberMeCookieManager. I have overriden the methods: getRememberedPrincipals(SubjectContext) and rememberIdentity(Subject, PrincipalCollection). getRememberedPrincipals retrieves the cookie value. rememberIdentity generates a random, non guessable nonce instead of the encrypted, serialized PrincipalCollection. Not sure what to call this value, I just went with nonce. This nonce and all the principals of the collection are written to a debase with jdbc.

getRememberedPrincipals reads the nonce from the cookie, if available, and retrieves the matching principals from the database.

The smoke tests do work :)

Open issues:

* Not sure how to get the proper realm name in getRememberedPrincipals. See the placeholder: “whatever" in the constructor of PrincipalCollection
* A nonce can have multiple principals and every principal can have multiple nonces.

The m:n relationship with nonces probably needs three tables. A select with joins would make a very long single line in shiro.ini. Would work, but it is not nice. The insert is even more complicated. Maybe it is better to not use shiro.ini in that case and let the user override some abstract method to load and store the principals. For example abstract loadPrincipals in DatabaseRememberMeCookieManager.

Hoping for a good discussion on this :)

Sorry if this message came several times. I keep forgetting what email address I use on different mailing lists.

/Björn

On 10. Jan 2018, at 16:56, Rob Young <[hidden email]> wrote:

I'd be interested to see this in action, I'd be happy to check out what you get up to!

On Wed, Jan 10, 2018 at 10:25 AM, Brian Demers <[hidden email]> wrote:
Probably an override, you will still need to add the cookie, so you should be able to override just what you need.



Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 
 
Cool!



--

Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

raupach
Hi Brian,

know you are busy. Could you give me some feedback on this?

kind regards
Björn

On 12. Jan 2018, at 16:44, Björn Raupach <[hidden email]> wrote:

Not sure where to talk about the proposed feature. JIRA Ticket? Mailing list or GitHub issue/pull request?

Anyways here is the link to the implementation: https://github.com/raupachz/shiro/tree/dbcookies The class is called DatabaseRememberMeCookieManager.java

This is more or less a simple proof of concept, so we have something to talk about.I am also not very familiar with the internals of Shiro and the terminology. So please correct me.

DatabaseRememberMeCookieManager inherits RememberMeCookieManager. I have overriden the methods: getRememberedPrincipals(SubjectContext) and rememberIdentity(Subject, PrincipalCollection). getRememberedPrincipals retrieves the cookie value. rememberIdentity generates a random, non guessable nonce instead of the encrypted, serialized PrincipalCollection. Not sure what to call this value, I just went with nonce. This nonce and all the principals of the collection are written to a debase with jdbc.

getRememberedPrincipals reads the nonce from the cookie, if available, and retrieves the matching principals from the database.

The smoke tests do work :)

Open issues:

* Not sure how to get the proper realm name in getRememberedPrincipals. See the placeholder: “whatever" in the constructor of PrincipalCollection
* A nonce can have multiple principals and every principal can have multiple nonces.

The m:n relationship with nonces probably needs three tables. A select with joins would make a very long single line in shiro.ini. Would work, but it is not nice. The insert is even more complicated. Maybe it is better to not use shiro.ini in that case and let the user override some abstract method to load and store the principals. For example abstract loadPrincipals in DatabaseRememberMeCookieManager.

Hoping for a good discussion on this :)

Sorry if this message came several times. I keep forgetting what email address I use on different mailing lists.

/Björn

On 10. Jan 2018, at 16:56, Rob Young <[hidden email]> wrote:

I'd be interested to see this in action, I'd be happy to check out what you get up to!

On Wed, Jan 10, 2018 at 10:25 AM, Brian Demers <[hidden email]> wrote:
Probably an override, you will still need to add the cookie, so you should be able to override just what you need.



Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 
 
Cool!



--


Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

Brian Demers
Looks like a good start, I left a comment on the nonce logic.  My JDBC is a little rusty though (which oddly makes me smile) so I might not be the best person to look at that.

There is probably some logic we can bubble up 
I almost forgot about this, but I was messing around with a JWT remember me manager, a while back:

If we create a encode/decode method that _should_ simplify your implementation.  Thoughts?
-Brian



On Fri, Jan 26, 2018 at 8:10 AM, Björn Raupach <[hidden email]> wrote:
Hi Brian,

know you are busy. Could you give me some feedback on this?

kind regards
Björn


On 12. Jan 2018, at 16:44, Björn Raupach <[hidden email]> wrote:

Not sure where to talk about the proposed feature. JIRA Ticket? Mailing list or GitHub issue/pull request?

Anyways here is the link to the implementation: https://github.com/raupachz/shiro/tree/dbcookies The class is called DatabaseRememberMeCookieManager.java

This is more or less a simple proof of concept, so we have something to talk about.I am also not very familiar with the internals of Shiro and the terminology. So please correct me.

DatabaseRememberMeCookieManager inherits RememberMeCookieManager. I have overriden the methods: getRememberedPrincipals(SubjectContext) and rememberIdentity(Subject, PrincipalCollection). getRememberedPrincipals retrieves the cookie value. rememberIdentity generates a random, non guessable nonce instead of the encrypted, serialized PrincipalCollection. Not sure what to call this value, I just went with nonce. This nonce and all the principals of the collection are written to a debase with jdbc.

getRememberedPrincipals reads the nonce from the cookie, if available, and retrieves the matching principals from the database.

The smoke tests do work :)

Open issues:

* Not sure how to get the proper realm name in getRememberedPrincipals. See the placeholder: “whatever" in the constructor of PrincipalCollection
* A nonce can have multiple principals and every principal can have multiple nonces.

The m:n relationship with nonces probably needs three tables. A select with joins would make a very long single line in shiro.ini. Would work, but it is not nice. The insert is even more complicated. Maybe it is better to not use shiro.ini in that case and let the user override some abstract method to load and store the principals. For example abstract loadPrincipals in DatabaseRememberMeCookieManager.

Hoping for a good discussion on this :)

Sorry if this message came several times. I keep forgetting what email address I use on different mailing lists.

/Björn

On 10. Jan 2018, at 16:56, Rob Young <[hidden email]> wrote:

I'd be interested to see this in action, I'd be happy to check out what you get up to!

On Wed, Jan 10, 2018 at 10:25 AM, Brian Demers <[hidden email]> wrote:
Probably an override, you will still need to add the cookie, so you should be able to override just what you need.



Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 
 
Cool!



--



Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

raupach
Hi Brian,

thanks for your time!

On 26. Jan 2018, at 17:03, Brian Demers <[hidden email]> wrote:

Looks like a good start, I left a comment on the nonce logic.  My JDBC is a little rusty though (which oddly makes me smile) so I might not be the best person to look at that.

Thanks. Fixed it. Replaced my self-made random nonce generator with org.apache.shiro.crypto.SecureRandomNumberGenerator. 

My JDBC better be not that rusty, even though we usually stick to MyBatis for persistence logic. I think the wrapper around the statements is fine but the actual SQL statements are very customer centric. Meaning you need to adapt it to your database schema. No idea if there is a easier solution. I was just thinking about our use case and how we would implement it.


There is probably some logic we can bubble up 
I almost forgot about this, but I was messing around with a JWT remember me manager, a while back:

If we create a encode/decode method that _should_ simplify your implementation.  Thoughts?
-Brian

Thanks for the pointer. Don’t know that much about JWT. From looking at the code it seems you are storing the subject in the cookie. Like the current implementation does. This might be different from what we are trying to achieve. We don’t want the subject in the cookie, but in the database. Otherwise I can’t invalidate cookies for a segment of our users on the server side. Is my assumption correct?




On Fri, Jan 26, 2018 at 8:10 AM, Björn Raupach <[hidden email]> wrote:
Hi Brian,

know you are busy. Could you give me some feedback on this?

kind regards
Björn


On 12. Jan 2018, at 16:44, Björn Raupach <[hidden email]> wrote:

Not sure where to talk about the proposed feature. JIRA Ticket? Mailing list or GitHub issue/pull request?

Anyways here is the link to the implementation: https://github.com/raupachz/shiro/tree/dbcookies The class is called DatabaseRememberMeCookieManager.java

This is more or less a simple proof of concept, so we have something to talk about.I am also not very familiar with the internals of Shiro and the terminology. So please correct me.

DatabaseRememberMeCookieManager inherits RememberMeCookieManager. I have overriden the methods: getRememberedPrincipals(SubjectContext) and rememberIdentity(Subject, PrincipalCollection). getRememberedPrincipals retrieves the cookie value. rememberIdentity generates a random, non guessable nonce instead of the encrypted, serialized PrincipalCollection. Not sure what to call this value, I just went with nonce. This nonce and all the principals of the collection are written to a debase with jdbc.

getRememberedPrincipals reads the nonce from the cookie, if available, and retrieves the matching principals from the database.

The smoke tests do work :)

Open issues:

* Not sure how to get the proper realm name in getRememberedPrincipals. See the placeholder: “whatever" in the constructor of PrincipalCollection
* A nonce can have multiple principals and every principal can have multiple nonces.

The m:n relationship with nonces probably needs three tables. A select with joins would make a very long single line in shiro.ini. Would work, but it is not nice. The insert is even more complicated. Maybe it is better to not use shiro.ini in that case and let the user override some abstract method to load and store the principals. For example abstract loadPrincipals in DatabaseRememberMeCookieManager.

Hoping for a good discussion on this :)

Sorry if this message came several times. I keep forgetting what email address I use on different mailing lists.

/Björn

On 10. Jan 2018, at 16:56, Rob Young <[hidden email]> wrote:

I'd be interested to see this in action, I'd be happy to check out what you get up to!

On Wed, Jan 10, 2018 at 10:25 AM, Brian Demers <[hidden email]> wrote:
Probably an override, you will still need to add the cookie, so you should be able to override just what you need.



Keep us posted!

Since we need this feature I can dedicate company time on this matter. Will work on this in my repo and open a pull request once I have something figured out. Might need some help troubleshooting. 
 
Cool!



--




Reply | Threaded
Open this post in threaded view
|

Re: RememberMeManager in Database

Brian Demers


Thanks for the pointer. Don’t know that much about JWT. From looking at the code it seems you are storing the subject in the cookie. Like the current implementation does. This might be different from what we are trying to achieve. We don’t want the subject in the cookie, but in the database. Otherwise I can’t invalidate cookies for a segment of our users on the server side. Is my assumption correct?


Right, I just didn't know if the proposed encode/decode methods I proposed to CookieRememberMeManager would make your code any easier