Skip to content
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

Custom Authentication Mechanisms for WebDAV and APIs #26742

Merged
merged 32 commits into from Mar 9, 2017

Conversation

joneug
Copy link
Contributor

@joneug joneug commented Nov 29, 2016

Description

The authentication mechanisms for securing WebDAV and APIs were extended to allow 3rd-party apps to provide additional authentication backends. In the WebDAV interface the dispatching of the OCA\DAV\Connector\Sabre::authInit event was added. For securing the API the interface IAuthModule was added. Apps can register their implementation of this interface in the info.xml file.

Related Issue

#10400

Motivation and Context

This, for example, allows the implementation of Bearer Authentication with OAuth 2.0 (see OAuth 2.0 app).

How Has This Been Tested?

The OAuth2 app's PHPUnit tests have been run on Travis CI with the following configurations:

  • PHP versions: 5.6, 7
  • Core branches: master
  • Databases: PostgreSQL, MySQL, SQLite

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@mention-bot
Copy link

@joneug, thanks for your PR! By analyzing the history of the files in this pull request, we identified @DeepDiver1975 to be a potential reviewer.

@CLAassistant
Copy link

CLAassistant commented Nov 29, 2016

CLA assistant check
All committers have signed the CLA.

@DeepDiver1975
Copy link
Member

@PhilippSchaffrath @Peter-Prochaska

* Most of the logic is handled, implementors just need to worry about
* the determineUsername method.
*/
abstract class AbstractBearer implements BackendInterface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class already exists in sabre dav - no need to add it here. THX

@guruz
Copy link
Contributor

guruz commented Dec 21, 2016

Linking #24995

@joneug joneug changed the title [WIP] OAuth 2.0 for WebDAV OAuth 2.0 for WebDAV Jan 24, 2017
@joneug
Copy link
Contributor Author

joneug commented Jan 24, 2017

@PhilippSchaffrath @DeepDiver1975 @butonic Please review the changes. Looking forward to your ideas.

@joneug
Copy link
Contributor Author

joneug commented Jan 24, 2017

I think the problem with the build failing in Jenkins is that the OAuth 2.0 app was added as a Submodule which requires additional commands for cloning. Would you like to use submodules or should I include the OAuth 2.0 app's files directly?

@joneug
Copy link
Contributor Author

joneug commented Feb 14, 2017

The dependencies between the core and the oauth2 app are now fully eliminated.

We need some plugin mechanism to this

I added IAuthModule as suggested.

And classes implementing this interface can be loaded via info.xml - basically just like the TwoFactor plugins

I updated the oauth2 app according to this. The AuthModule class is registered in info.xml under auth-modules.

And within the UserSession instead if calling tryTokenLogin, tryBearerLogin, trySessionLogin ....
We just loop over all registered modules

I added the function tryAuthModuleLogin that implements this loop. I don't see a way of replacing tryTokenLogin with this loop as tokens are not implemented with an app. What do you think?

@joneug joneug changed the title OAuth 2.0 for WebDAV and APIs Custom Authentication Mechanisms for WebDAV and APIs Mar 2, 2017
@joneug
Copy link
Contributor Author

joneug commented Mar 2, 2017

I changed the title of the PR, because now OAuth 2.0 is fully capsulated in the app and this PR addresses the more general problem of adding 3rd-party authentication backends.

Furthermore, I added the function getUserPassword to the IAuthModule interface in order to be able to trigger the hooks. Where to get the password from should not concern this PR.

As a side note: in the OAuth 2.0 app an empty string is returned because we are not handling any passwords at all. Consequently, only master key encryption is working, but this restriction exists when using Shibboleth, too.

Lastly, I added loading of additional AuthBackends for the webdav interface.

@joneug
Copy link
Contributor Author

joneug commented Mar 2, 2017

Could you please review the changes?

Additionally, considering a backport to stable9.1 would be nice since the changes are relatively small and there is high interest form our side in using this mechanism for implementing OAuth 2.0 in ownCloud 9.1.

*/
public function tryAuthModuleLogin(IRequest $request) {
/** @var IAppManager $appManager */
$appManager = OC::$server->query('AppManager');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please inject appManager as parameter in the ctor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to inject the AppManager, but when changing the registration of UserSession in Server.php (see here) I get the following error:

PHP Fatal error:  Maximum function nesting level of '256' reached

Inside the closure for the registerService function, $appManager = $c->getAppManager(); is called over and over again. Any ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay then let's keep it this way

}

/** @var IAuthModule $authModule */
$authModule = OC::$server->query($class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding a type check?

if ($authModule instanceof IAuthModule) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@DeepDiver1975
Copy link
Member

hmmm ... two tests are failing on oracle ....

23:15:18 There were 2 failures:
23:15:18 
23:15:18 1) Test\Files\External\Service\GlobalStoragesServiceTest::testUpdateStorage with data set #1 (array('mountpoint', 'identifier:\Test\Files\Extern...ackend', 'identifier:\Auth\Mechanism', array('value1', 'value2', 'testPassword'), array('user1', 'user2'), array(), 15))
23:15:18 Failed asserting that two arrays are equal.
23:15:18 --- Expected
23:15:18 +++ Actual
23:15:18 @@ @@
23:15:18  Array (
23:15:18 -    0 => 'user1'
23:15:18 -    1 => 'user2'
23:15:18 +    0 => 'user2'
23:15:18 +    1 => 'user1'
23:15:18  )
23:15:18 
23:15:18 /var/lib/jenkins/workspace/owncloud-core_core_PR-26742-JCGXUYPGPX2CBJQVJBQBPP3QLMW2OPW6JKKJVSVR77ZQ5M6LTFKQ/tests/lib/Files/External/Service/GlobalStoragesServiceTest.php:185
23:15:18 
23:15:18 2) Test\Files\External\Service\GlobalStoragesServiceTest::testUpdateStorage with data set #3 (array('mountpoint', 'identifier:\Test\Files\Extern...ackend', 'identifier:\Auth\Mechanism', array('value1', 'value2', 'testPassword'), array('user1', 'user2'), array('group1', 'group2'), 15))
23:15:18 Failed asserting that two arrays are equal.
23:15:18 --- Expected
23:15:18 +++ Actual
23:15:18 @@ @@
23:15:18  Array (
23:15:18 -    0 => 'user1'
23:15:18 -    1 => 'user2'
23:15:18 +    0 => 'user2'
23:15:18 +    1 => 'user1'
23:15:18  )
23:15:18 

@joneug
Copy link
Contributor Author

joneug commented Mar 9, 2017

I pulled the changes in master branch and now the Jenkins build was successful. But the travis build failed:

$ sh -c "if [ '$TEST_DAV' = '1' ]; then bash apps/dav/tests/travis/$TC/install.sh; fi"
bash: apps/dav/tests/travis/selenium/install.sh: No such file or directory

The command "sh -c "if [ '$TEST_DAV' = '1' ]; then bash apps/dav/tests/travis/$TC/install.sh; fi"" failed and exited with 127 during .

Are there errors in the build script (see changes of commit cac897b)?

@DeepDiver1975
Copy link
Member

I pulled the changes in master branch and now the Jenkins build was successful. But the travis build failed:

I'd say this is unrelated ..... let's merge

@DeepDiver1975 DeepDiver1975 merged commit d35a58d into owncloud:master Mar 9, 2017
@DeepDiver1975
Copy link
Member

Thanks a lot! @joneug and your team! Great job!

@joneug
Copy link
Contributor Author

joneug commented Mar 9, 2017

What do you think about backporting to 9.1?

Additionally, considering a backport to stable9.1 would be nice since the changes are relatively small and there is high interest form our side in using this mechanism for implementing OAuth 2.0 in ownCloud 9.1.

@DeepDiver1975
Copy link
Member

What do you think about backporting to 9.1?

@PVince81 what's your opionion? THX

@joneug
Copy link
Contributor Author

joneug commented Mar 13, 2017

I created a backport in PR #27370.

@lock
Copy link

lock bot commented Aug 3, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Aug 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants