Since such condition can happen only if the same user tries to login from 2 mediums at the same, this is rarely happen. However that slight chance may prevent that particular user from login to the system until all or all-1 access tokens are expired. Using the UNIQUE constraint will definitely will provide a better security and furthermore will make the model more meaningful. On the other hand this will break the token replacing functionality since it first create a token (at this time there are 2 tokens in the db) and delete the last one.
What I propose is writing a separate query to replace tokens instead of using save & delete queries separately and furthermore we can use a new query to save tokens without affecting the UNIQUE constraints so that no need to mess with threading & @Transactional properties. On Mon, Apr 9, 2018 at 2:06 PM, Francesco Chicchiriccò <ilgro...@apache.org> wrote: > On 09/04/2018 10:14, Isuranga Perera wrote: > >> The Read Committed isolation level ensures that data can only be read by a >> transaction if it is in the committed state. It doesn't completely isolate >> this transaction(create) hence some other transaction can still use this >> method which results in the behavior I explained previously. Ideally If >> we're gonna use @Transactional annotation the isolation level should be >> serialized for create operation. Please correct me If I'm wrong. >> > > I see your point - while I don't completely agree about the likelihood of > such race condition to actually happen. > > At worse, you might end up in having two distinct JWT (Access Tokens) > values for a single user, which will anyway be subject to expiration due to > > https://github.com/apache/syncope/blob/master/core/provision > ing-java/src/main/java/org/apache/syncope/core/provisioni > ng/java/job/ExpiredAccessTokenCleanup.java > > For additional security, we might want to impose a UNIQUE constraint on > > https://github.com/apache/syncope/blob/master/core/persisten > ce-jpa/src/main/java/org/apache/syncope/core/persistenc > e/jpa/entity/JPAAccessToken.java#L48 > > (not sure to remember why the column is currently set as nullable, though). > With UNIQUE owner, the step (5) in your sequence below will fail anyway. > > Again, given the chances that the race condition applies, and considering > what would be the harm (nearly none, to me), I would rather avoid any > modification rather than imposing the UNIQUE constraint. > > > Regards. > > On Mon, Apr 9, 2018 at 1:12 PM, Francesco Chicchiriccò < >> ilgro...@apache.org> >> wrote: >> >> On 09/04/2018 09:30, Isuranga Perera wrote: >>> >>> Hi Francesco, >>>> >>>> Yes there is @Transactional annotation. But it haven't set the isolation >>>> property as well as the propagation property. Based on the default >>>> values >>>> set this thread safe problem will still occur. Please correct me if I'm >>>> wrong. >>>> >>>> The transaction isolation level is set in >>> >>> https://github.com/apache/syncope/blob/master/core/persisten >>> ce-jpa/src/main/resources/domains/MasterDomain.xml#L57-L59 >>> >>> Regards. >>> >>> >>> On Mon, Apr 9, 2018 at 12:20 PM, Francesco Chicchiriccò < >>> >>>> ilgro...@apache.org> wrote: >>>> >>>> On 09/04/2018 08:46, Isuranga Perera wrote: >>>> >>>>> Hi Francesco, >>>>> >>>>>> I will take a scenario. Suppose a scenario where thread A & thread B >>>>>> try >>>>>> to login user admin. >>>>>> >>>>>> 1. thread A checks if a token exist for the user admin (suppose >>>>>> currently there is no token associated with the admin) >>>>>> 2. Then thread A execute following logic[1] to create and save the >>>>>> token. >>>>>> 3. Before thread A save the token for user admin thread B checks >>>>>> if a >>>>>> token exist for user admin (since the toked created by thread A >>>>>> is >>>>>> not yet saved *exist == null*) >>>>>> 4. Then thread A complete the creation of token (and saving) >>>>>> 5. Thread B also complete the creation and saving of the token. >>>>>> >>>>>> That way there can be 2 tokens for a particular user. >>>>>> >>>>>> >>>>>> You analysis does not take into any account the fact of the >>>>>> constraints >>>>>> >>>>> imposed by the @Service annotation in >>>>> >>>>> https://github.com/apache/syncope/blob/master/core/rest-cxf/ >>>>> src/main/java/org/apache/syncope/core/rest/cxf/service/Acces >>>>> sTokenServiceImpl.java#L35 >>>>> >>>>> (e.g. the place when external requests can come in) nor by the >>>>> @Transactional annotation injected into >>>>> >>>>> https://github.com/apache/syncope/blob/master/core/logic/ >>>>> src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java#L80 >>>>> >>>>> via >>>>> >>>>> https://github.com/apache/syncope/blob/master/core/logic/ >>>>> src/main/java/org/apache/syncope/core/logic/AbstractTra >>>>> nsactionalLogic.java#L29 >>>>> >>>>> Regards. >>>>> >>>>> [1] https://github.com/apache/syncope/blob/master/core/provision >>>>> >>>>> ing-java/src/main/java/org/apache/syncope/core/provisioni >>>>>> ng/java/data/AccessTokenDataBinderImpl.java#L119 >>>>>> >>>>>> Best Regards >>>>>> Isuranga Perera >>>>>> >>>>>> On Mon, Apr 9, 2018 at 11:42 AM, Francesco Chicchiriccò < >>>>>> ilgro...@apache.org <mailto:ilgro...@apache.org>> wrote: >>>>>> >>>>>> On 09/04/2018 07:07, Isuranga Perera wrote: >>>>>> >>>>>> Hi All, >>>>>> >>>>>> Token create method in AccessTokenDataBinderImpl[1] is not >>>>>> thread safe. >>>>>> >>>>>> >>>>>> Could you please explain why you're affirming this? >>>>>> >>>>>> This could result in several problems including >>>>>> >>>>>> * Exist 2 different access token for a particular user at >>>>>> a >>>>>> given >>>>>> time which may result in an exception thrown by method >>>>>> call[2] >>>>>> since it expects a single token a given user. >>>>>> >>>>>> In addition to that token replace is implemented as a >>>>>> combination of 2 different functionalities. Since the method >>>>>> is not thread safe this may cause some unexpected behaviors >>>>>> (since there can be 2 tokens exist for a particular user. >>>>>> same >>>>>> scenario as above). >>>>>> >>>>>> Appreciate your insight on the $subject. >>>>>> >>>>>> >>>>>> [1] >>>>>> https://github.com/apache/sync >>>>>> ope/blob/master/core/provision >>>>>> ing-java/src/main/java/org/apache/syncope/core/provisioni >>>>>> ng/java/data/AccessTokenDataBinderImpl.java#L104 >>>>>> <https://github.com/apache/syn >>>>>> cope/blob/master/core/provisio >>>>>> ning-java/src/main/java/org/apache/syncope/core/provisioni >>>>>> ng/java/data/AccessTokenDataBinderImpl.java#L104> >>>>>> >>>>>> [2] >>>>>> https://github.com/apache/sync >>>>>> ope/blob/master/core/provision >>>>>> ing-java/src/main/java/org/apache/syncope/core/provisioni >>>>>> ng/java/data/AccessTokenDataBinderImpl.java#L113 >>>>>> <https://github.com/apache/syn >>>>>> cope/blob/master/core/provisio >>>>>> ning-java/src/main/java/org/apache/syncope/core/provisioni >>>>>> ng/java/data/AccessTokenDataBinderImpl.java#L113> >>>>>> >>>>>> Best Regards >>>>>> Isuranga Perera >>>>>> >>>>> > > -- > Francesco Chicchiriccò > > Tirasa - Open Source Excellence > http://www.tirasa.net/ > > Member at The Apache Software Foundation > Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail > http://home.apache.org/~ilgrosso/ > >