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

[ZEPPELIN-2598] Securing Zeppelin with OpenID Connect #2373

Closed
wants to merge 7 commits into from

Conversation

andreaTP
Copy link
Contributor

What is this PR for?

Integrating Open ID connect login into Zeppelin leveraging Shiro(already present) and Pac4J( that needs to be in the classpath).
Modifications done here should not affect any existing mechanisms but simply integrates and enable new once.

What type of PR is it?

[Improvement]

What is the Jira issue?

[ZEPPELIN-2598]

Questions:

  • Does the licenses files need update?
  • Is there breaking changes for older versions?
  • Does this needs documentation?

@@ -86,7 +86,7 @@
<i ng-if="!navbar.connected" class="fa fa-circle server-disconnected"
uib-tooltip="WebSocket Disconnected" tooltip-placement="bottom" style="margin-top: 7px; vertical-align: top"></i>
<button ng-if="ticket" class="nav-btn dropdown-toggle" type="button" data-toggle="dropdown" style="margin:11px 5px 0 0; padding-left: 0px;">
<span class="username">{{ticket.principal}}</span>
<span class="username">{{ticket.screenUsername}}</span>
Copy link
Member

Choose a reason for hiding this comment

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

and the reason for this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, buji library uses the principal field to store token information so we need to display proper user name instead of the whole content of the token.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

is that going to change the output for cases other than buji?

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 made a filter with:

if ($rootScope.ticket.principal.startsWith("#Pac4j")) {

I hope is reasonably enough

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is not "out of the box" but zeppelin could now support this integration

Choose a reason for hiding this comment

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

Is it only limited to having pac4j on the classpath and necessary configuration in shiro.ini? Or does it required some code changes in Zeppelin as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pac4j and maybe other dependencies on classpath and configuration is enough! We are integrating with Keycloak i.e.

Copy link

@HarvinderBhullar HarvinderBhullar Jul 19, 2017

Choose a reason for hiding this comment

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

I tried with following shiro.ini configuration with all the required jars on classpath. It is not working. I am getting following error

authentication token of type [class org.apache.shiro.authc.UsernamePasswordToken] could not be authenticated by any configured realms.

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager

securityManager.sessionManager = $sessionManager

oidcConfig = org.pac4j.oidc.config.OidcConfiguration
oidcConfig.discoveryURI = https://accounts.google.com/.well-known/openid-configuration
oidcConfig.clientId = 167480702619-8e1lo80dnu8bpk3k0lvvj27noin97vu9.apps.googleusercontent.com
oidcConfig.secret =MhMme_Ik6IH2JMnAT6MFIfee
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig

config = org.pac4j.core.config.Config

requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleAdmin.elements = admin

oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = oidcClient
clients = org.pac4j.core.client.Clients
clients.callbackUrl = http://localhost:8086/api/callback
clients.clients = $oidcClient

config.clients = $clients
config.authorizers = admin:$requireRoleAdmin

pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
securityManager.subjectFactory = $pac4jSubjectFactory

callbackFilter = io.buji.pac4j.filter.CallbackFilter
callbackFilter.defaultUrl = http://localhost:8086
callbackFilter.config = $config

securityManager.sessionManager.globalSessionTimeout = 86400000
shiro.loginUrl = /api/login

[urls]
/api/callback = callbackFilter

Choose a reason for hiding this comment

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

I am setting up Google OpenID client, the login on Zeppelin should take me to Google account but it is opening Zeppelin Login form, what setup is needed in shiro.ini to correct this behavior?

<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusions>
</dependency>
Copy link
Member

Choose a reason for hiding this comment

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

could you add to the LICENSE file on these dependencies?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added license for pac4j, buji is again with Apache 2 shoul I add a specific file also for that one?

Copy link
Member

Choose a reason for hiding this comment

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

You'll need to list license of those dependencies in zeppelin-distribution/src/bin-license/LICENSE file.
licenses/LICENSE-pac4j-1.9.8 also need to be moved to zeppelin-distribution/src/bin-license/licenses while those dependency will be included in binary package only.

pac4j-oidc brings some transitive dependencies. License of those dependencies also need to be taken care.

[INFO] +- org.pac4j:pac4j-oidc:jar:1.9.8:compile
[INFO] |  +- com.nimbusds:oauth2-oidc-sdk:jar:5.24.2:compile
[INFO] |  |  +- javax.mail:mail:jar:1.4.7:compile
[INFO] |  |  |  \- javax.activation:activation:jar:1.1:compile
[INFO] |  |  +- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
[INFO] |  |  +- org.apache.commons:commons-collections4:jar:4.1:compile
[INFO] |  |  +- net.minidev:json-smart:jar:1.3.1:compile
[INFO] |  |  \- com.nimbusds:lang-tag:jar:1.4.3:compile (version selected from constraint [1.4.3,))
[INFO] |  \- com.nimbusds:nimbus-jose-jwt:jar:4.26:compile

pom.xml Outdated
<groupId>org.pac4j</groupId>
<artifactId>pac4j-oidc</artifactId>
<version>${pac4j.version}</version>
</dependency>
Copy link
Member

Choose a reason for hiding this comment

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

if these are only needed for zeppelin-server, do we need these here?

#securityManager.subjectFactory = $pac4jSubjectFactory
#oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
#oidcSecurityFilter.config = $config
#oidcSecurityFilter.clients = oidcClient
Copy link
Member

Choose a reason for hiding this comment

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

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 make some explanations in the docs, the fact is that both pac4j and buji are really highly configurable and most of configuration is provider dependent, this in theory result in free other integrations done by just changing shiro.ini but I'm not such an expert ...

<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusions>
</dependency>
Copy link
Member

Choose a reason for hiding this comment

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

You'll need to list license of those dependencies in zeppelin-distribution/src/bin-license/LICENSE file.
licenses/LICENSE-pac4j-1.9.8 also need to be moved to zeppelin-distribution/src/bin-license/licenses while those dependency will be included in binary package only.

pac4j-oidc brings some transitive dependencies. License of those dependencies also need to be taken care.

[INFO] +- org.pac4j:pac4j-oidc:jar:1.9.8:compile
[INFO] |  +- com.nimbusds:oauth2-oidc-sdk:jar:5.24.2:compile
[INFO] |  |  +- javax.mail:mail:jar:1.4.7:compile
[INFO] |  |  |  \- javax.activation:activation:jar:1.1:compile
[INFO] |  |  +- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
[INFO] |  |  +- org.apache.commons:commons-collections4:jar:4.1:compile
[INFO] |  |  +- net.minidev:json-smart:jar:1.3.1:compile
[INFO] |  |  \- com.nimbusds:lang-tag:jar:1.4.3:compile (version selected from constraint [1.4.3,))
[INFO] |  \- com.nimbusds:nimbus-jose-jwt:jar:4.26:compile

pom.xml Outdated
@@ -105,7 +105,9 @@
<commons.io.version>2.4</commons.io.version>
<commons.collections.version>3.2.1</commons.collections.version>
<commons.logging.version>1.1.1</commons.logging.version>
<shiro.version>1.2.3</shiro.version>
<shiro.version>1.3.2</shiro.version>
Copy link
Member

Choose a reason for hiding this comment

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

Could you also update shiro version in zeppelin-distribution/src/bin-license/LICENSE?

#callbackFilter = io.buji.pac4j.filter.CallbackFilter
#callbackFilter.defaultUrl = http://<zeppelin ip>:8080
#callbackFilter.config = $config

Copy link
Contributor

@khalidhuseynov khalidhuseynov Jun 1, 2017

Choose a reason for hiding this comment

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

i think we'll need something like #securityManager.realms = $pac4jRealm here, isn't it?

@@ -55,6 +55,33 @@ user3 = password4, role2
#zeppelinHubRealm.zeppelinhubUrl = https://www.zeppelinhub.com
#securityManager.realms = $zeppelinHubRealm

### A sample for configuring OIDC Pac4J managed login(i.e. Keycloak)
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we could separate config here in similar way as in documentation, by separating oidc, clients, callbackFilter configuration by new line

@khalidhuseynov
Copy link
Contributor

khalidhuseynov commented Jun 1, 2017

i've just tried to login using the config info from online demo for oidc-client in https://demo.c2id.com/oidc-client using modified config below

oidcConfig = org.pac4j.oidc.config.OidcConfiguration
oidcConfig.discoveryURI = https://demo.c2id.com/oidc-client/cb
oidcConfig.clientId = 000123
oidcConfig.secret = 7wKJNYFaKKg4FxUdi8_R75GGYsiWezvAbcdN1uSumE4
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig
clients = org.pac4j.core.client.Clients
clients.callbackUrl = http://localhost:8080/api/callback
clients.clients = $oidcClient
requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
#requireRoleAdmin.elements = <your role>
config = org.pac4j.core.config.Config
config.clients = $clients
#config.authorizers = admin:$requireRoleAdmin
pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
securityManager.subjectFactory = $pac4jSubjectFactory
oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = oidcClient
callbackFilter = io.buji.pac4j.filter.CallbackFilter
callbackFilter.defaultUrl = http://localhost:8080
callbackFilter.config = $config
securityManager.realms = $pac4jRealm

...

/api/callback = callbackFilter
#/** = anon
/** = authc

but getting exception

ERROR [2017-06-01 14:49:39,711] ({qtp764577347-20} LoginRestApi.java[postLogin]:111) - Exception in login: 
org.apache.shiro.authc.pam.UnsupportedTokenException: Realm [io.buji.pac4j.realm.Pac4jRealm@734cf9ff] does not support authentication token [org.apache.shiro.authc.UsernamePasswordToken - alice, rememberMe=false].  Please ensure that the appropriate Realm implementation is configured correctly or that the realm accepts AuthenticationTokens of this type.
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:178)
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
	at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
	at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:270)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:256)
	at org.apache.zeppelin.rest.LoginRestApi.postLogin(LoginRestApi.java:80)

please let me know if you can see any apparent misconfiguration i did

@1ambda
Copy link
Member

1ambda commented Jun 1, 2017

Hi, I have a question. Does this PR means, zeppelin can be OAuth client? For example github, google, ...

@andreaTP
Copy link
Contributor Author

andreaTP commented Jun 1, 2017

@1ambda potentially yes

@khalidhuseynov thanks for pointing out a public server I can test! I will go through later on

B.t.w. I realized that the MVP to get this working is just upgrading shiro and the ui triggers,
the rest of the libraries can be provided on an ad-hoc basis (i.e. in a lib dir) without any need of packaging them into zeppelin itself, this will enable also users to choose the preferred version.

@1ambda
Copy link
Member

1ambda commented Jun 1, 2017

Then can we add documentation including examples? (e.g for Google OAuth, Github OAuth, ,..)

That's because users are having trouble when they setup security things.
But there is no proper documentation. LDAP is one example.

So, it would be nice to include documentation like

  • How to setup Google OAuth
  • How to setup Github OAuth
  • ...

@andreaTP
Copy link
Contributor Author

andreaTP commented Jun 2, 2017

@1ambda To be honest I'm not such an expert and I'm just integrating from a technical POV a solution that other experts in team found.

I will love to have such documentation too, but I cannot realistically propose myself for writing it... sorry.

@andreaTP
Copy link
Contributor Author

andreaTP commented Jun 6, 2017

do this minimal and cleaned up version needs anything else to be worked out in order to be merged?

@@ -96,8 +96,8 @@ The following components are provided under Apache License.
(Apache 2.0) Lucene Suggest (org.apache.lucene:lucene-suggest:5.3.1 - http://lucene.apache.org/lucene-parent/lucene-suggest)
(Apache 2.0) Elasticsearch: Core (org.elasticsearch:elasticsearch:2.1.0 - http://nexus.sonatype.org/oss-repository-hosting.html/parent/elasticsearch)
(Apache 2.0) Joda convert (org.joda:joda-convert:1.8.1 - http://joda-convert.sourceforge.net)
(Apache 2.0) Shiro Core (org.apache.shiro:shiro-core:1.2.3 - https://shiro.apache.org)
(Apache 2.0) Shiro Web (org.apache.shiro:shiro-web:1.2.3 - https://shiro.apache.org)
(Apache 2.0) Shiro Core (org.apache.shiro:shiro-core:1.3.2 - https://shiro.apache.org)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@felixcheung already updated

@volumeint
Copy link
Contributor

volumeint commented Jun 9, 2017 via email

@andreaTP
Copy link
Contributor Author

I sincerely think that this implementation is enough to unlock the usage of pac4j, buji (due to the rest of updates sent there).
I think that the name parsing can be refactored later on, actual implementation is not optimal but "good enough" to me(i.e. I have no cases where it fails), in case @volumeint could you share your configuration to login through other oidc providers in docs in another PR?

Please let try to finalize this in this week
cc. @Leemoonsoo @1ambda @felixcheung

@andreaTP
Copy link
Contributor Author

ping

@volumeint
Copy link
Contributor

I just submitted a pull request to buji-pac4j to make the value of Principal.getName() configurable via shiro.ini. We just have to wait for it to be accepted and released. I will provide some documentation on integrating with one of the social OAuth providers after I clean up my zeppelin pull request. An ounce of code can save a pound of documentation.

@necosta
Copy link
Contributor

necosta commented Jun 19, 2017

@andreaTP , a bit strange why Jenkins succeeds, running "mvn clean package -DskipTests" fails with the below errors introduced in this pull request. Can you have a look? Thanks.

.../zeppelin-web/src/app/app.js
[INFO] 166:1 error More than 1 blank line not allowed no-multiple-empty-lines
[INFO] 180:3 error Unexpected var, use let or const instead no-var
[INFO] 180:27 error Extra space before value for key 'headers' key-spacing
[INFO] 181:5 error Strings must use singlequote quotes
[INFO] 181:25 error Strings must use singlequote quotes
[INFO] 182:5 error Expected indentation of 2 spaces but found 4 indent
[INFO] 189:50 error Strings must use singlequote quotes
[INFO] 190:18 error Strings must use singlequote quotes
[INFO] 196:5 error Unexpected var, use let or const instead no-var
[INFO] 197:30 error Expected '===' and instead saw '==' eqeqeq
[INFO] 197:49 error Expected '!==' and instead saw '!=' eqeqeq
[INFO] 198:7 error Expected space or tab after '//' in comment spaced-comment

@andreaTP
Copy link
Contributor Author

@necosta checked again but it works for me and on CI ... I have had this problem once try to fetch and pull and see if this solves

@necosta
Copy link
Contributor

necosta commented Jun 19, 2017

@andreaTP , sorry, I forgot to add. You need to test on top of latest master. nokia:keycloak is 45 commits behind apache:master . That could explain why it's not failing here. Thanks.

@andreaTP
Copy link
Contributor Author

rebased on top of master and fixed style issues, this PR is taking too long for reviewers...

@andreaTP andreaTP closed this Jun 19, 2017
@andreaTP andreaTP reopened this Jun 19, 2017
Copy link
Member

@felixcheung felixcheung left a comment

Choose a reason for hiding this comment

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

this looks reasonable to me. I'd suggest adding on documentation on how to use all these but that could come a bit later.

})
}, function (errorResponse) {
// Handle error case
let redirect = errorResponse.headers('Location')
if (errorResponse.status === 401 && redirect !== undefined) {
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't redirect be error code 3xx instead of 4xx?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the redirect could not be performed automatically, since we are doing our requests with ajax.
In this case the answer is 401 https://github.com/pac4j/pac4j/blob/master/pac4j-core/src/main/java/org/pac4j/core/client/IndirectClient.java#L88

@necosta
Copy link
Contributor

necosta commented Jun 23, 2017

LGTM

@andreaTP
Copy link
Contributor Author

Hi @SarunasG , actually I'm facing the very same situation here ...
I haven't had enough time to dig deeper, but it looks like that 'logout` action is not triggering the REST call to do a logout from the Oidc authority.
Eventually we will try to find a solution but please keep me copied if you can go further in your investigation too.

@felixcheung
Copy link
Member

Hi! Please redirect your questions to [email protected] or open a JIRA if there is a bug?

@zhengkai6
Copy link

Is there any document or example to tell us how to use SSO function in zeppelin?

@zhengkai6
Copy link

zhengkai6 commented Jun 13, 2018

@1ambda Do you have a sample code to test this function? @andreaTP

@felixcheung
Copy link
Member

@xixikaikai #2373 (comment)

@andreaTP
Copy link
Contributor Author

I think the link is broken.
here: https://github.com/apache/zeppelin/pull/2373/files

@andreaTP
Copy link
Contributor Author

actually a more detailed description is available here: https://github.com/apache/zeppelin/pull/2552/files

@zhengkai6
Copy link

@andreaTP thanks, I am now trying keycloak with the oidc

@zhengkai6
Copy link

BTW can I use local keycloak for oidc connect to zeppelin?
I now set up a local env of keycloak @andreaTP

@andreaTP
Copy link
Contributor Author

@xixikaikai sure, we are using keycloak in production

@zhengkai6
Copy link

hello I've put the following libs into my 0.7.3's zeppelin lib folder,
But the errors occur, can I ask you for a help?

image
@andreaTP

@zhengkai6
Copy link

$ cat logs/zeppelin-zhengkai-zhengkais-MacBook-Pro.local.out ZEPPELIN_CLASSPATH: ::/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/lib/interpreter/*:/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/lib/*:/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/*::/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/conf Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/beanutils/BeanIntrospector at org.apache.shiro.config.IniSecurityManagerFactory.<init>(IniSecurityManagerFactory.java:64) at org.apache.shiro.config.IniSecurityManagerFactory.<init>(IniSecurityManagerFactory.java:68) at org.apache.shiro.config.IniSecurityManagerFactory.<init>(IniSecurityManagerFactory.java:73) at org.apache.zeppelin.utils.SecurityUtils.initSecurityManager(SecurityUtils.java:55) at org.apache.zeppelin.server.ZeppelinServer.setupRestApiContextHandler(ZeppelinServer.java:324) at org.apache.zeppelin.server.ZeppelinServer.main(ZeppelinServer.java:179) Caused by: java.lang.ClassNotFoundException: org.apache.commons.beanutils.BeanIntrospector at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 6 more

@zhengkai6
Copy link

image

@zhengkai6
Copy link

Again I've added more jars to zeppelin-0.7.3, but the error occur once more

image

@zhengkai6
Copy link

Zeppelin is restarting ZEPPELIN_CLASSPATH: ::/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/lib/interpreter/*:/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/lib/*:/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/*::/Users/zhengkai/Downloads/zeppelin-0.7.3-bin-all/conf Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/beanutils/BeanIntrospector at org.apache.shiro.config.IniSecurityManagerFactory.<init>(IniSecurityManagerFactory.java:64) at org.apache.shiro.config.IniSecurityManagerFactory.<init>(IniSecurityManagerFactory.java:68) at org.apache.shiro.config.IniSecurityManagerFactory.<init>(IniSecurityManagerFactory.java:73) at org.apache.zeppelin.utils.SecurityUtils.initSecurityManager(SecurityUtils.java:55) at org.apache.zeppelin.server.ZeppelinServer.setupRestApiContextHandler(ZeppelinServer.java:324) at org.apache.zeppelin.server.ZeppelinServer.main(ZeppelinServer.java:179) Caused by: java.lang.ClassNotFoundException: org.apache.commons.beanutils.BeanIntrospector at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 6 more

@zhengkai6
Copy link

image

@zhengkai6
Copy link

@SarunasG @1ambda @khalidhuseynov @andreaTP Hello, is there any doc of details for me to add libs in 0.7.3 and by changing the shiro.ini config file to support open id?

@liuhengzhi liuhengzhi deleted the keycloak branch July 3, 2018 09:25
@ajaygk95
Copy link

ajaygk95 commented Sep 8, 2018

Hello,
Has anyone tried with zeppelin with keycloak ?

@ajaygk95
Copy link

@SarunasG @1ambda @khalidhuseynov @andreaTP Hello, is there any doc of details for me to add libs in 0.7.3 and by changing the shiro.ini config file to support open id?

Hello @xixikaikai ,
I am using zeppelin 0.8.0 and with the below changes i am able to integrate it with keycloak.

Dependencies to be added in zeppelin-0.8.0 lib folder:
buji-pac4j-3.0.0.jar
lang-tag-1.4.3.jar
json-smart-1.3.1.jar
commons-lang3-3.5.jar
commons-collections4-4.1.jar
pac4j-core-2.3.1.jar
oauth2-oidc-sdk-5.24.2.jar
mail-1.4.7.jar
shiro-crypto-hash-1.4.0.jar
shiro-crypto-core-1.4.0.jar
shiro-crypto-cipher-1.4.0.jar
shiro-core-1.4.0.jar
shiro-config-ogdl-1.4.0.jar
shiro-config-core-1.4.0.jar
shiro-cache-1.4.0.jar
pac4j-oidc-2.3.1.jar
slf4j-api-1.7.25.jar
shiro-web-1.4.0.jar
shiro-lang-1.4.0.jar
shiro-event-1.4.0.jar

I have added the shiro.ini conf and dependency in the attachment.
dep.txt

asfgit pushed a commit that referenced this pull request Oct 1, 2018
### What is this PR for?
Bump Up the Shiro version in zeppelin from 1.3.2 to 1.4.0. Bumping up the Shiro version will help in using the newer pac4j versions. This will also help in integrating Zeppelin and OpenID Connect using latest versions of pac4j. Pac4j also mentions that it is compatible with Shiro 1.4 version.

### What type of PR is it?
Improvement

### What is the Jira issue?
ZEPPELIN-3791

### How should this be tested?
**Basic User Authentication**

- Use the attached Basic Shiro.ini file
- Start Zeppelin with "bin/zeppelin-daemon.sh start"
- Using browser open zeppelin UI
- Try login using user1/password2 - Login successful
- Try login using user1/wrong - Login fails as expected

**Testing with KeyCloak - Based on Shiro + Pac4j + buij-pac4j**

- Use the attached keycloakshiro.ini which uses the zeppelin realm and zeppelin-client
- Copy the dependency jars to zeppelin lib folder (list of jars attached)
- Configure keycloak with realms and users matching keycloakshiro.ini
- Start Zeppelin with "bin/zeppelin-daemon.sh start".
- Using browser open zeppelin UI
- You will be redirected to Keycloak UI.
- Try login using username/password registered in keycloak - success
- Try login using user/wrongPassword -  Login fails as expected
For more details related to Zeppelin keycloak integration refer to [PR-2373](#2373)

[dependency-jar.txt](https://github.com/apache/zeppelin/files/2415208/dependency-jar.txt)
[keycloakshiro.ini.txt](https://github.com/apache/zeppelin/files/2415209/keycloakshiro.ini.txt)
[shiro.ini.txt](https://github.com/apache/zeppelin/files/2415210/shiro.ini.txt)

Author: G <[email protected]>

Closes #3188 from ajaygk95/master and squashes the following commits:

dab87e0 [G] ZEPPELIN-3791: Bump-Up shiro version from 1.3.2 to 1.4.0
@pmuntyanu
Copy link

@ajaygk95 , thanks for sharing - it worked for us! There are two not resolved questions still:

  • is it possible to define roles and users and have different permissions by using OpenID and Keycloak?
  • how to get real username in zeppelin in the top right corner instead of id from Keycloak?

@ajaygk95
Copy link

ajaygk95 commented May 1, 2019

@ajaygk95 , thanks for sharing - it worked for us! There are two not resolved questions still:

* is it possible to define roles and users and have different permissions by using OpenID and Keycloak?

* how to get real username in zeppelin in the top right corner instead of id from Keycloak?

Hi @pmuntyanu ,
I am still figuring out the authorization part. No clue on this yet
For the username issue you can use pac4jRealm.principalNameAttribute = preferred_username under pac4jRealm section in your shiro.ini. This will display the actual username in your zeppelin UI.

@pmuntyanu
Copy link

Hi @ajaygk95 , it worked! I even changed the preferred_username to the email - for my use case, it is better. With regards to the roles and permissions, I think it is possible to use keycloak roles and RequireAnyRoleAuthorizer which we can setup via java-bean-like shiro.ini file. In the end, it is just an idea and I have not tested it yet, but it looks like it can work. More details are here and example is here

@doudoumai
Copy link

doudoumai commented Jan 27, 2020

I succeeded to make zeppelin SSO with keycloak, with roles & logout successfully.
For roles:

  1. rewrite (or inherit from) Pac4jRealm to overwrite doGetAuthenticationInfo to fetch the roles into a member variable (and provide getter for this variable). I have not yet figured out why doGetAuthorizationInfo is not called.
  2. In SecurityUtils, the getRoles function needs to be updated to access the Pac4jRealm instance to get the roles from the above member variable

For logout, you do not need to provide logout handler in shiro.ini, instead you need to:

  1. Configure the Pac4jRealm (the one you overwrite or inherit from) with a new parameter in shiro.ini for the keycloak logout address, which is in the form of "http://<ip>:<port>/auth/realms/<realm>/protocol/openid-connect/logout?redirect_uri=".
    Please make sure you follow the above pattern, or else Keycloak will complain the redirect uri is not valid when logout.
  2. update logout function in LoginRestApi: if the realm is Pac4jRealm (the one you overwrite or inherit from), the send the response with redirect as below:
    Map<String, String> data = new HashMap<>();
    data.put("redirectURL", ((ZeppelinPac4jRealm) realm).getLogoutUrl());
    response = new JsonResponse(Status.UNAUTHORIZED, "", data);

With the above setting, when logout, it will redirect to keycloak logout address (appending zeppelin home address after "redirect_uri" automatically) and it will logout the session from keycloak successfully. After logout, it will then redirect to your zeppelin server home page, which will redirect you to keycloak login page.

Of course, the above looks not that elegant, say:

  • the doGetAuthorizationInfo shall be called in the flow
  • the keycloak baseUri is configured in "oidcConfigure" but can not be reused in logout and we have to retype similar url pattern in Pac4jRealm's variable for logout
  • the SecurityUtils have to instrument the realm to fetch the roles, which I believe the zeppelin itself has to fix, not only for Pac4jRealm but also other realms.

@alexanderswerdlow
Copy link

I've tried many times following some of the configurations above, but for some strange reason, keep getting redirected to http://ZEPPELIN_ROOT/null. It appears that a request for http://ZEPPELIN_ROOT/api/security/ticket is denied ("unauthorized request") and subsequently redirected to/null (It does this very quickly, had to use a packet sniffer to discover this). Strangely enough, however, I can manually access http://ZEPPELIN_ROOT/api/security/ticket, login, and then once I manually navigate to http://ZEPPELIN_ROOT it shows I'm logged in.

I'm really not sure where the null is coming from and not sure what to do (or if OpenID Connect is still supported). I attached my shiro.ini file below (localhost:8085 is my Keycloak Root and localhost:8080 is my Zeppelin Root).

shiro.txt

@alexott
Copy link
Contributor

alexott commented Jun 22, 2020

@alexanderswerdlow
Copy link

@alexott I have done so here but haven't received any response

@BradyYue
Copy link

BradyYue commented Sep 9, 2021

@alexott I have done so here but haven't received any response

Hello this
I encountered the same problem as yours, the configuration is almost the same, and when the ticket is executed, a 401 appears and the callback reaches null. At present, the problem is solved. Is there any good way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.