You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ol...@apache.org on 2016/11/16 11:51:01 UTC
[3/3] ambari git commit: AMBARI-18821. Logsearch support KNOX SSO
(oleewere)
AMBARI-18821. Logsearch support KNOX SSO (oleewere)
Change-Id: I7d275de0ed17f02234ca290811236b2211653bae
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/02e6251d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/02e6251d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/02e6251d
Branch: refs/heads/branch-2.5
Commit: 02e6251dc702eef70c2db0f4a43c98d23d494a89
Parents: ce4c0cd
Author: oleewere <ol...@gmail.com>
Authored: Thu Nov 10 12:12:04 2016 +0100
Committer: oleewere <ol...@gmail.com>
Committed: Wed Nov 16 12:47:32 2016 +0100
----------------------------------------------------------------------
.../ambari-logsearch-portal/pom.xml | 6 +
.../ambari/logsearch/conf/AuthPropsConfig.java | 62 +++++++
.../ambari/logsearch/conf/SecurityConfig.java | 55 ++++--
.../web/filters/LogsearchJWTFilter.java | 181 +++++++++++++++++++
...LogsearchSecurityContextFormationFilter.java | 3 +-
...rchUsernamePasswordAuthenticationFilter.java | 1 -
.../web/model/JWTAuthenticationToken.java | 53 ++++++
.../configuration/logsearch-properties.xml | 63 +++++++
.../LOGSEARCH/0.5.0/themes/theme.json | 87 ++++++++-
ambari-web/app/data/HDP2/site_properties.js | 21 +++
10 files changed, 515 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/pom.xml b/ambari-logsearch/ambari-logsearch-portal/pom.xml
index be58732..6bacd23 100755
--- a/ambari-logsearch/ambari-logsearch-portal/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-portal/pom.xml
@@ -37,6 +37,7 @@
<jetty-version>9.2.11.v20150529</jetty-version>
<swagger.version>1.5.8</swagger.version>
<spring-data-solr.version>2.0.2.RELEASE</spring-data-solr.version>
+ <jjwt.version>0.6.0</jjwt.version>
</properties>
<profiles>
<!-- Dev Profile Start -->
@@ -767,5 +768,10 @@
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt</artifactId>
+ <version>${jjwt.version}</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
index 67ddd1f..54cc10c 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
@@ -21,6 +21,8 @@ package org.apache.ambari.logsearch.conf;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
+import java.util.List;
+
@Configuration
public class AuthPropsConfig {
@@ -38,6 +40,18 @@ public class AuthPropsConfig {
private String externalAuthLoginUrl;
@Value("${logsearch.login.credentials.file:user_pass.json}")
private String credentialsFile;
+ @Value("${logsearch.auth.jwt.enabled:false}")
+ private boolean authJwtEnabled;
+ @Value("${logsearch.auth.jwt.provider_url:}")
+ private String providedUrl;
+ @Value("${logsearch.auth.jwt.public_key:}")
+ private String publicKey;
+ @Value("${logsearch.auth.jwt.cookie.name:hadoop-jwt}")
+ private String cookieName;
+ @Value("${logsearch.auth.jwt.query.param.original_url:originalUrl=}")
+ private String originalUrlQueryParam;
+ @Value("#{'${logsearch.auth.jwt.audiances:}'.split(',')}")
+ private List<String> audiences;
public boolean isAuthFileEnabled() {
return authFileEnabled;
@@ -94,4 +108,52 @@ public class AuthPropsConfig {
public void setAuthExternalEnabled(boolean authExternalEnabled) {
this.authExternalEnabled = authExternalEnabled;
}
+
+ public boolean isAuthJwtEnabled() {
+ return authJwtEnabled;
+ }
+
+ public void setAuthJwtEnabled(boolean authJwtEnabled) {
+ this.authJwtEnabled = authJwtEnabled;
+ }
+
+ public String getProvidedUrl() {
+ return providedUrl;
+ }
+
+ public void setProvidedUrl(String providedUrl) {
+ this.providedUrl = providedUrl;
+ }
+
+ public String getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(String publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public String getCookieName() {
+ return cookieName;
+ }
+
+ public void setCookieName(String cookieName) {
+ this.cookieName = cookieName;
+ }
+
+ public String getOriginalUrlQueryParam() {
+ return originalUrlQueryParam;
+ }
+
+ public void setOriginalUrlQueryParam(String originalUrlQueryParam) {
+ this.originalUrlQueryParam = originalUrlQueryParam;
+ }
+
+ public List<String> getAudiences() {
+ return audiences;
+ }
+
+ public void setAudiences(List<String> audiences) {
+ this.audiences = audiences;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
index d3db110..7a6c69c 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
@@ -18,11 +18,13 @@
*/
package org.apache.ambari.logsearch.conf;
+import com.google.common.collect.Lists;
import org.apache.ambari.logsearch.web.authenticate.LogsearchAuthFailureHandler;
import org.apache.ambari.logsearch.web.authenticate.LogsearchAuthSuccessHandler;
import org.apache.ambari.logsearch.web.authenticate.LogsearchLogoutSuccessHandler;
import org.apache.ambari.logsearch.web.filters.LogsearchAuthenticationEntryPoint;
import org.apache.ambari.logsearch.web.filters.LogsearchKRBAuthenticationFilter;
+import org.apache.ambari.logsearch.web.filters.LogsearchJWTFilter;
import org.apache.ambari.logsearch.web.filters.LogsearchSecurityContextFormationFilter;
import org.apache.ambari.logsearch.web.filters.LogsearchUsernamePasswordAuthenticationFilter;
import org.apache.ambari.logsearch.web.security.LogsearchAuthenticationProvider;
@@ -34,11 +36,21 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
+import org.springframework.security.web.util.matcher.OrRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+import javax.inject.Inject;
+import java.util.List;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
+ @Inject
+ private AuthPropsConfig authPropsConfig;
+
@Override
protected void configure(HttpSecurity http) throws Exception {
http
@@ -46,20 +58,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.sessionManagement()
.sessionFixation()
.newSession()
- .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
+ .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.authorizeRequests()
- .antMatchers("/login.html").permitAll()
- .antMatchers("/styles/**").permitAll()
- .antMatchers("/fonts/**").permitAll()
- .antMatchers("/fonts/**").permitAll()
- .antMatchers("/scripts/**").permitAll()
- .antMatchers("/libs/**").permitAll()
- .antMatchers("/images/**").permitAll()
- .antMatchers("/templates/**").permitAll()
- .antMatchers("/favicon.ico").permitAll()
- .antMatchers("/api/v1/public/**").permitAll()
- .antMatchers("/api/v1/swagger.json").permitAll()
+ .requestMatchers(requestMatcher()).permitAll()
.antMatchers("/**").authenticated()
.and()
.authenticationProvider(logsearchAuthenticationProvider())
@@ -70,8 +72,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.authenticationEntryPoint(logsearchAuthenticationEntryPoint())
.and()
.addFilterBefore(logsearchUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
- .addFilterBefore(new LogsearchKRBAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
+ .addFilterBefore(logsearchKRBAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(securityContextFormationFilter(), FilterSecurityInterceptor.class)
+ .addFilterBefore(logsearchJwtFilter(), LogsearchSecurityContextFormationFilter.class)
.logout()
.logoutUrl("/logout.html")
.deleteCookies("JSESSIONID")
@@ -94,6 +97,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
@Bean
+ public LogsearchJWTFilter logsearchJwtFilter() throws Exception {
+ LogsearchJWTFilter filter = new LogsearchJWTFilter(requestMatcher(), authPropsConfig);
+ filter.setAuthenticationManager(authenticationManagerBean());
+ filter.setAuthenticationSuccessHandler(new LogsearchAuthSuccessHandler());
+ filter.setAuthenticationFailureHandler(new LogsearchAuthFailureHandler());
+ return filter;
+ }
+
+ @Bean
public LogsearchAuthenticationEntryPoint logsearchAuthenticationEntryPoint() {
LogsearchAuthenticationEntryPoint entryPoint = new LogsearchAuthenticationEntryPoint("/login.html");
entryPoint.setForceHttps(false);
@@ -109,4 +121,21 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
return filter;
}
+ @Bean
+ public RequestMatcher requestMatcher() {
+ List<RequestMatcher> matchers = Lists.newArrayList();
+ matchers.add(new AntPathRequestMatcher("/login.html"));
+ matchers.add(new AntPathRequestMatcher("/logout.html"));
+ matchers.add(new AntPathRequestMatcher("/styles/**"));
+ matchers.add(new AntPathRequestMatcher("/fonts/**"));
+ matchers.add(new AntPathRequestMatcher("/scripts/**"));
+ matchers.add(new AntPathRequestMatcher("/libs/**"));
+ matchers.add(new AntPathRequestMatcher("/templates/**"));
+ matchers.add(new AntPathRequestMatcher("/favicon.ico"));
+ matchers.add(new AntPathRequestMatcher("/api/v1/public/**"));
+ matchers.add(new AntPathRequestMatcher("/api/v1/swagger.json"));
+ matchers.add(new AntPathRequestMatcher("/api/v1/swagger.yaml"));
+ return new OrRequestMatcher(matchers);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchJWTFilter.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchJWTFilter.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchJWTFilter.java
new file mode 100644
index 0000000..1bc7231
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchJWTFilter.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.logsearch.web.filters;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.SignatureException;
+import org.apache.ambari.logsearch.conf.AuthPropsConfig;
+import org.apache.ambari.logsearch.web.model.JWTAuthenticationToken;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+
+public class LogsearchJWTFilter extends AbstractAuthenticationProcessingFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LogsearchJWTFilter.class);
+
+ private static final String PEM_HEADER = "-----BEGIN CERTIFICATE-----\n";
+ private static final String PEM_FOOTER = "\n-----END CERTIFICATE-----";
+
+ private AuthPropsConfig authPropsConfig;
+
+ public LogsearchJWTFilter(RequestMatcher requestMatcher, AuthPropsConfig authPropsConfig) {
+ super(new NegatedRequestMatcher(requestMatcher));
+ this.authPropsConfig = authPropsConfig;
+ }
+
+ @Override
+ public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
+ if (StringUtils.isEmpty(authPropsConfig.getProvidedUrl())) {
+ throw new BadCredentialsException("Authentication provider URL must not be null or empty.");
+ }
+ if (StringUtils.isEmpty(authPropsConfig.getPublicKey())) {
+ throw new BadCredentialsException("Public key for signature validation must be provisioned.");
+ }
+
+ try {
+ Claims claims = Jwts
+ .parser()
+ .setSigningKey(parseRSAPublicKey(authPropsConfig.getPublicKey()))
+ .parseClaimsJws(getJWTFromCookie(request))
+ .getBody();
+
+ String userName = claims.getSubject();
+ LOG.info("USERNAME: " + userName);
+ LOG.info("URL = " + request.getRequestURL());
+ if (StringUtils.isNotEmpty(claims.getAudience()) && !authPropsConfig.getAudiences().contains(claims.getAudience())) {
+ throw new IllegalArgumentException(String.format("Audience validation failed. (Not found: %s)", claims.getAudience()));
+ }
+ Authentication authentication = new JWTAuthenticationToken(userName, authPropsConfig.getPublicKey());
+ authentication.setAuthenticated(true);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ return authentication;
+ } catch (ExpiredJwtException | MalformedJwtException | SignatureException | IllegalArgumentException e) {
+ LOG.info("URL = " + request.getRequestURL());
+ LOG.warn("Error during JWT authentication: ", e.getMessage());
+ throw new BadCredentialsException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (!authPropsConfig.isAuthJwtEnabled() || isAuthenticated(authentication)) {
+ chain.doFilter(req, res);
+ return;
+ }
+ super.doFilter(req, res, chain);
+ }
+
+ @Override
+ protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
+ super.successfulAuthentication(request, response, chain, authResult);
+ response.sendRedirect(request.getRequestURL().toString() + getOriginalQueryString(request));
+ }
+
+ @Override
+ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
+ super.unsuccessfulAuthentication(request, response, failed);
+ String loginUrl = constructLoginURL(request);
+ response.sendRedirect(loginUrl);
+ }
+
+ private String getJWTFromCookie(HttpServletRequest req) {
+ String serializedJWT = null;
+ Cookie[] cookies = req.getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (authPropsConfig.getCookieName().equals(cookie.getName())) {
+ LOG.info(authPropsConfig.getCookieName() + " cookie has been found and is being processed");
+ serializedJWT = cookie.getValue();
+ break;
+ }
+ }
+ }
+ return serializedJWT;
+ }
+
+ private RSAPublicKey parseRSAPublicKey(String pem) throws ServletException {
+ String fullPem = PEM_HEADER + pem + PEM_FOOTER;
+ try {
+ CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ ByteArrayInputStream is = new ByteArrayInputStream(fullPem.getBytes("UTF8"));
+
+ X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
+ return (RSAPublicKey) cer.getPublicKey();
+ } catch (CertificateException ce) {
+ String message;
+ if (pem.startsWith(PEM_HEADER)) {
+ message = "CertificateException - be sure not to include PEM header "
+ + "and footer in the PEM configuration element.";
+ } else {
+ message = "CertificateException - PEM may be corrupt";
+ }
+ throw new ServletException(message, ce);
+ } catch (UnsupportedEncodingException uee) {
+ throw new ServletException(uee);
+ }
+ }
+
+ private String constructLoginURL(HttpServletRequest request) {
+ String delimiter = "?";
+ if (authPropsConfig.getProvidedUrl().contains("?")) {
+ delimiter = "&";
+ }
+ return authPropsConfig.getProvidedUrl() + delimiter
+ + authPropsConfig.getOriginalUrlQueryParam() + "="
+ + request.getRequestURL().toString() + getOriginalQueryString(request);
+ }
+
+ private String getOriginalQueryString(HttpServletRequest request) {
+ String originalQueryString = request.getQueryString();
+ return (originalQueryString == null) ? "" : "?" + originalQueryString;
+ }
+
+ private boolean isAuthenticated(Authentication authentication) {
+ return authentication != null && !(authentication instanceof AnonymousAuthenticationToken) && authentication.isAuthenticated();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchSecurityContextFormationFilter.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchSecurityContextFormationFilter.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchSecurityContextFormationFilter.java
index 1320278..b427749 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchSecurityContextFormationFilter.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchSecurityContextFormationFilter.java
@@ -88,8 +88,7 @@ public class LogsearchSecurityContextFormationFilter extends GenericFilterBean {
httpResponse.addCookie(cookie);
}
// [1]get the context from session
- LogSearchContext context = (LogSearchContext) httpSession
- .getAttribute(LOGSEARCH_SC_SESSION_KEY);
+ LogSearchContext context = (LogSearchContext) httpSession.getAttribute(LOGSEARCH_SC_SESSION_KEY);
if (context == null) {
context = new LogSearchContext();
httpSession.setAttribute(LOGSEARCH_SC_SESSION_KEY, context);
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchUsernamePasswordAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchUsernamePasswordAuthenticationFilter.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchUsernamePasswordAuthenticationFilter.java
index 85688a2..24ec2d4 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchUsernamePasswordAuthenticationFilter.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchUsernamePasswordAuthenticationFilter.java
@@ -36,7 +36,6 @@ public class LogsearchUsernamePasswordAuthenticationFilter extends UsernamePassw
public void setRememberMeServices(RememberMeServices rememberMeServices) {
super.setRememberMeServices(rememberMeServices);
-
}
@Override
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/model/JWTAuthenticationToken.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/model/JWTAuthenticationToken.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/model/JWTAuthenticationToken.java
new file mode 100644
index 0000000..35175b6
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/web/model/JWTAuthenticationToken.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.logsearch.web.model;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Collection;
+
+public class JWTAuthenticationToken extends AbstractAuthenticationToken {
+
+ private String credential;
+
+ private String principal;
+
+ public JWTAuthenticationToken(String principal, String credential) {
+ super((Collection)null);
+ this.principal = principal;
+ this.credential = credential;
+ }
+
+ public JWTAuthenticationToken(String principal, String credential, Collection<? extends GrantedAuthority> authorities) {
+ super(authorities);
+ this.principal = principal;
+ this.credential = credential;
+ }
+
+ @Override
+ public Object getCredentials() {
+ return credential;
+ }
+
+ @Override
+ public Object getPrincipal() {
+ return principal;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-properties.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-properties.xml b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-properties.xml
index febeffd..9dcd5cf 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-properties.xml
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-properties.xml
@@ -173,4 +173,67 @@
<description>The path and query of the external server used to authenticate</description>
<on-ambari-upgrade add="true"/>
</property>
+ <property>
+ <name>logsearch.auth.jwt.enabled</name>
+ <value>false</value>
+ <display-name>JWT authentication enabled</display-name>
+ <description>Enable JWT based authentication for Log Search portal</description>
+ <value-attributes>
+ <type>value-list</type>
+ <overridable>false</overridable>
+ <entries>
+ <entry>
+ <value>true</value>
+ <label>ON</label>
+ </entry>
+ <entry>
+ <value>false</value>
+ <label>OFF</label>
+ </entry>
+ </entries>
+ <selection-cardinality>1</selection-cardinality>
+ </value-attributes>
+ <on-ambari-upgrade add="true"/>
+ </property>
+ <property>
+ <name>logsearch.auth.jwt.provider_url</name>
+ <value/>
+ <display-name>JWT authentication provider url</display-name>
+ <description>URL to the JWT authentication server</description>
+ <on-ambari-upgrade add="true"/>
+ </property>
+ <property>
+ <name>logsearch.auth.jwt.query.param.original_url</name>
+ <value>originalUrl</value>
+ <display-name>JWT original url query param</display-name>
+ <description>Name of the original request URL which is used to redirect to Log Search Portal</description>
+ <on-ambari-upgrade add="true"/>
+ </property>
+ <property>
+ <name>logsearch.auth.jwt.cookie.name</name>
+ <value>hadoop-jwt</value>
+ <display-name>JWT cookie name</display-name>
+ <description>The name of the cookie that contains the JWT token</description>
+ <on-ambari-upgrade add="true"/>
+ </property>
+ <property>
+ <name>logsearch.auth.jwt.audiances</name>
+ <value/>
+ <display-name>JWT expected audiances</display-name>
+ <description>Comma separated list of acceptable audiences for the JWT token</description>
+ <value-attributes>
+ <empty-value-valid>true</empty-value-valid>
+ </value-attributes>
+ <on-ambari-upgrade add="true"/>
+ </property>
+ <property>
+ <name>logsearch.auth.jwt.public_key</name>
+ <value/>
+ <display-name>JWT authentication signing key</display-name>
+ <description>PEM formatted public key for JWT token without the header and the footer</description>
+ <value-attributes>
+ <type>content</type>
+ </value-attributes>
+ <on-ambari-upgrade add="true"/>
+ </property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/themes/theme.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/themes/theme.json b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/themes/theme.json
index 2ed6474..0193689 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/themes/theme.json
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/themes/theme.json
@@ -11,7 +11,7 @@
"display-name": "Settings",
"layout": {
"tab-columns": "2",
- "tab-rows": "1",
+ "tab-rows": "2",
"sections": [
{
"name": "section-logsearch-server",
@@ -38,6 +38,25 @@
"column-span": "1"
}
]
+ },
+ {
+ "name": "section-logsearch-sso",
+ "display-name": "Single Sign-On",
+ "row-index": "1",
+ "column-index": "1",
+ "row-span": "3",
+ "column-span": "1",
+ "section-columns": "1",
+ "section-rows": "5",
+ "subsections": [
+ {
+ "name": "subsection-logsearch-server-sso-col1",
+ "row-index": "1",
+ "column-index": "0",
+ "row-span": "3",
+ "column-span": "1"
+ }
+ ]
}
]
}
@@ -71,6 +90,54 @@
{
"config": "logsearch-properties/logsearch.collection.audit.logs.replication.factor",
"subsection-name": "subsection-logsearch-server-col2"
+ },
+ {
+ "config": "logsearch-properties/logsearch.auth.jwt.enabled",
+ "subsection-name": "subsection-logsearch-server-sso-col1"
+ },
+ {
+ "config": "logsearch-properties/logsearch.auth.jwt.provider_url",
+ "subsection-name": "subsection-logsearch-server-sso-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "logsearch-properties/logsearch.auth.jwt.enabled"
+ ],
+ "if": "${logsearch-properties/logsearch.auth.jwt.enabled}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "logsearch-properties/logsearch.auth.jwt.public_key",
+ "subsection-name": "subsection-logsearch-server-sso-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "logsearch-properties/logsearch.auth.jwt.enabled"
+ ],
+ "if": "${logsearch-properties/logsearch.auth.jwt.enabled}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
}
]
},
@@ -135,6 +202,24 @@
}
]
}
+ },
+ {
+ "config": "logsearch-properties/logsearch.auth.jwt.enabled",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "logsearch-properties/logsearch.auth.jwt.provider_url",
+ "widget": {
+ "type": "text-field"
+ }
+ },
+ {
+ "config": "logsearch-properties/logsearch.auth.jwt.public_key",
+ "widget": {
+ "type": "directories"
+ }
}
]
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/02e6251d/ambari-web/app/data/HDP2/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2/site_properties.js b/ambari-web/app/data/HDP2/site_properties.js
index 5be3b5a..d61d4aa 100644
--- a/ambari-web/app/data/HDP2/site_properties.js
+++ b/ambari-web/app/data/HDP2/site_properties.js
@@ -2264,6 +2264,27 @@ var hdp2properties = [
"category": "Advanced logsearch-properties",
"index": 11
},
+ {
+ "name": "logsearch.auth.jwt.audiances",
+ "serviceName": "LOGSEARCH",
+ "filename": "logsearch-properties.xml",
+ "category": "Advanced logsearch-properties",
+ "index": 12
+ },
+ {
+ "name": "logsearch.auth.jwt.cookie.name",
+ "serviceName": "LOGSEARCH",
+ "filename": "logsearch-properties.xml",
+ "category": "Advanced logsearch-properties",
+ "index": 13
+ },
+ {
+ "name": "logsearch.auth.jwt.query.param.original_url",
+ "serviceName": "LOGSEARCH",
+ "filename": "logsearch-properties.xml",
+ "category": "Advanced logsearch-properties",
+ "index": 14
+ },
/*infra-solr-client-log4j*/
{
"name": "infra_solr_client_log_dir",