blob: f170efc3fca7e6931e66b2cc44cd5305bed5182c [file] [log] [blame]
/**
* 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.oodt.security.sso;
import org.apache.commons.codec.binary.Base64;
import org.apache.oodt.security.sso.opensso.SSOMetKeys;
import org.apache.oodt.security.sso.opensso.SSOProxy;
import org.apache.oodt.security.sso.opensso.SingleSignOnException;
import org.apache.oodt.security.sso.opensso.UserDetails;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.Cookie;
/**
*
* Connects to OpenSSO's authorization endpoint and authenticates a user,
* implementing the CAS {@link AbstractWebBasedSingleSignOn} interface. This
* class can be used in e.g., CAS curator to link into Open SSO.
*/
public class OpenSSOImpl extends AbstractWebBasedSingleSignOn implements
SSOMetKeys {
private static final Logger LOG = Logger.getLogger(OpenSSOImpl.class
.getName());
private SSOProxy ssoProxy;
/**
* Default constructor.
*/
public OpenSSOImpl() {
this.ssoProxy = new SSOProxy();
}
public String getCurrentUsername() {
String cookieVal = this.getCookieVal(USER_COOKIE_KEY);
if (cookieVal == null) {
// let's try and get the SSO token
// and pull the username from there
String ssoToken = this.getSSOToken();
if (ssoToken != null) {
UserDetails details;
try {
details = this.ssoProxy.getUserAttributes(ssoToken);
} catch (Exception e) {
LOG.log(Level.SEVERE, e.getMessage());
return UNKNOWN_USER;
}
return details.getAttributes().getMetadata(UID_ATTRIBUTE_NAME) != null ? details
.getAttributes().getMetadata(UID_ATTRIBUTE_NAME) : UNKNOWN_USER;
} else {
return UNKNOWN_USER;
}
} else {
return new String(Base64.decodeBase64(cookieVal.getBytes()));
}
}
public boolean getLastConnectionStatus() {
return this.isLoggedIn();
}
public boolean isLoggedIn() {
// TODO: make sure the token is valid?
return (this.getSSOToken() != null);
}
public boolean login(String username, String password) {
String ssoToken;
try {
ssoToken = this.ssoProxy.authenticate(username, password);
} catch (Exception e) {
LOG.log(Level.SEVERE, e.getMessage());
return false;
}
this.addCookie(SSO_COOKIE_KEY, "\"" + ssoToken + "\"");
this.addCookie(USER_COOKIE_KEY,
"\"" + new String(Base64.encodeBase64(username.getBytes())) + "\"");
return true;
}
public void logout() {
this.ssoProxy.logout(this.getSSOToken());
this.clearCookie(SSO_COOKIE_KEY);
this.clearCookie(USER_COOKIE_KEY);
}
/**
* Gets the SSO groups for the LMMP user, identified by her
* <code>ssoAuth</code>, where her User ID is provided by
* {@link OpenSSOImpl#getCurrentUsername()} and her Token is provided by
* {@link OpenSSOImpl#getSSOToken()}.
*
* @return A {@link List} of String LMMP groups for the User.
* @throws SingleSignOnException
* If any error (e.g., HTTP REST error) occurs.
* @throws IOException If the SSO token cannot be read.
*/
public List<String> getGroupsForUser() throws IOException, SingleSignOnException {
String token = this.getSSOToken();
if (token == null) {
return Collections.EMPTY_LIST;
} else {
UserDetails details = this.ssoProxy.getUserAttributes(token);
// groups are formatted in this response to include whole
// principals, like lmmp-infra,...principal
// so split on "," and take the first token to get the group name
List<String> groups = new Vector<String>();
for (String rawGroup : details.getRoles()) {
groups.add(rawGroup.split(",")[0]);
}
return groups;
}
}
/*
* (non-Javadoc)
*
* @see
* org.apache.oodt.security.sso.SingleSignOn#retrieveGroupsForUser(java.lang
* .String)
*/
@Override
public List<String> retrieveGroupsForUser(String username) {
// FIXME: not implemented yet
return Collections.EMPTY_LIST;
}
protected String getSSOToken() {
String cookieVal = this.getCookieVal(SSO_COOKIE_KEY);
if (cookieVal != null) {
return cookieVal;
} else {
return null;
}
}
private String getCookieVal(String name) {
Cookie[] cookies = this.req.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
return cookie.getValue().startsWith("\"")
&& cookie.getValue().endsWith("\"") ? cookie.getValue().substring(
1, cookie.getValue().length() - 1) : cookie.getValue();
}
}
return null;
}
private void addCookie(String name, String val) {
Cookie userCookie = new Cookie(name, val);
userCookie.setPath("/");
userCookie.setMaxAge((int) (System.currentTimeMillis() + (60 * 15)));
this.res.addCookie(userCookie);
}
private void clearCookie(String name) {
Cookie userCookie = new Cookie(name, "blank");
userCookie.setPath("/");
userCookie.setMaxAge(0);
this.res.addCookie(userCookie);
}
}