From e63b03f3d7e4851e008e4bb4d184982c2c0bd229 Mon Sep 17 00:00:00 2001 From: WuKong Date: Tue, 24 May 2016 17:13:17 +0200 Subject: odl/aaa clone Change-Id: I2b72c16aa3245e02d985a2c6189aacee7caad36e Signed-off-by: WuKong --- .../aaa/federation/FederationEndpoint.java | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 odl-aaa-moon/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationEndpoint.java (limited to 'odl-aaa-moon/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationEndpoint.java') diff --git a/odl-aaa-moon/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationEndpoint.java b/odl-aaa-moon/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationEndpoint.java new file mode 100644 index 00000000..6ac76c0a --- /dev/null +++ b/odl-aaa-moon/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationEndpoint.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2014, 2015 Hewlett-Packard Development Company, L.P. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.federation; + +import static javax.servlet.http.HttpServletResponse.SC_CREATED; +import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.oltu.oauth2.as.issuer.OAuthIssuer; +import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl; +import org.apache.oltu.oauth2.as.issuer.UUIDValueGenerator; +import org.apache.oltu.oauth2.as.response.OAuthASResponse; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; +import org.apache.oltu.oauth2.common.message.OAuthResponse; +import org.opendaylight.aaa.AuthenticationBuilder; +import org.opendaylight.aaa.ClaimBuilder; +import org.opendaylight.aaa.api.Authentication; +import org.opendaylight.aaa.api.AuthenticationException; +import org.opendaylight.aaa.api.Claim; + +/** + * An endpoint for claim-based authentication federation (in-bound). + * + * @author liemmn + * + */ +public class FederationEndpoint extends HttpServlet { + + private static final long serialVersionUID = -5553885846238987245L; + + /** An in-bound authentication claim */ + static final String AUTH_CLAIM = "AAA-CLAIM"; + + private static final String UNAUTHORIZED = "unauthorized"; + + private transient OAuthIssuer oi; + + @Override + public void init(ServletConfig config) throws ServletException { + oi = new OAuthIssuerImpl(new UUIDValueGenerator()); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, + ServletException { + try { + createRefreshToken(req, resp); + } catch (Exception e) { + error(resp, SC_UNAUTHORIZED, e.getMessage()); + } + } + + // Create a refresh token + private void createRefreshToken(HttpServletRequest req, HttpServletResponse resp) + throws OAuthSystemException, IOException { + Claim claim = (Claim) req.getAttribute(AUTH_CLAIM); + oauthRefreshTokenResponse(resp, claim); + } + + // Build OAuth refresh token response from the given claim mapped and + // injected by the external IdP + private void oauthRefreshTokenResponse(HttpServletResponse resp, Claim claim) + throws OAuthSystemException, IOException { + if (claim == null) { + throw new AuthenticationException(UNAUTHORIZED); + } + + String userName = claim.user(); + // Need to have at least a mapped username! + if (userName == null) { + throw new AuthenticationException(UNAUTHORIZED); + } + + String domain = claim.domain(); + // Need to have at least a domain! + if (domain == null) { + throw new AuthenticationException(UNAUTHORIZED); + } + + String userId = userName + "@" + domain; + + // Create an unscoped ODL context from the external claim + Authentication auth = new AuthenticationBuilder(new ClaimBuilder(claim).setUserId(userId) + .build()).setExpiration(tokenExpiration()).build(); + + // Create OAuth response + String token = oi.refreshToken(); + OAuthResponse r = OAuthASResponse + .tokenResponse(SC_CREATED) + .setRefreshToken(token) + .setExpiresIn(Long.toString(auth.expiration())) + .setScope( + // Use mapped domain if there is one, else list + // all the ones that this user has access to + (claim.domain().isEmpty()) ? listToString(ServiceLocator.getInstance() + .getIdmService().listDomains(userId)) : claim.domain()) + .buildJSONMessage(); + // Cache this token... + ServiceLocator.getInstance().getTokenStore().put(token, auth); + write(resp, r); + } + + // Token expiration + private long tokenExpiration() { + return ServiceLocator.getInstance().getTokenStore().tokenExpiration(); + } + + // Space-delimited string from a list of strings + private String listToString(List list) { + StringBuffer sb = new StringBuffer(); + for (String s : list) { + sb.append(s).append(" "); + } + return sb.toString().trim(); + } + + // Emit an error OAuthResponse with the given HTTP code + private void error(HttpServletResponse resp, int httpCode, String error) { + try { + OAuthResponse r = OAuthResponse.errorResponse(httpCode).setError(error) + .buildJSONMessage(); + write(resp, r); + } catch (Exception e1) { + // Nothing to do here + } + } + + // Write out an OAuthResponse + private void write(HttpServletResponse resp, OAuthResponse r) throws IOException { + resp.setStatus(r.getResponseStatus()); + PrintWriter pw = resp.getWriter(); + pw.print(r.getBody()); + pw.flush(); + pw.close(); + } +} -- cgit 1.2.3-korg