/* Copyright (c) 2011 Danish Maritime Authority. * * Licensed 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 net.maritimecloud.mms.server.security.impl; import com.typesafe.config.Config; import net.maritimecloud.mms.server.security.AuthenticationException; import net.maritimecloud.mms.server.security.AuthenticationHandler; import net.maritimecloud.mms.server.security.AuthenticationToken; import net.maritimecloud.mms.server.security.AuthenticationTokenHandler; import net.maritimecloud.mms.server.security.ClientVerificationException; import net.maritimecloud.mms.server.security.ClientVerificationHandler; import javax.servlet.http.HttpServletRequest; /** * Handles authentication and client verification according to static configuration rules. * * <h2>Authentication Token Resolution</h2> * Implements the {@code AuthenticationTokenHandler} interface and may be used if a proxy SSL-server * (e.g. nginx) has already authenticated the client and stamped the principal into a header * of the upgrade request.<br> * The security configuration must name the request header via the "principal-header" configuration option. * * <h2>Authentication</h2> * Implements the {@code AuthenticationHandler} interface and will * flag a successful authentication attempt if a principal is defined. * * <h2>Client Verification</h2> * Implements the {@code ClientVerificationHandler} interface and will * check that the principal is identical to the client ID. */ @SuppressWarnings("unused") public class FixedConfSecurityHandler implements AuthenticationTokenHandler, AuthenticationHandler, ClientVerificationHandler { private Config conf; /** {@inheritDoc} */ @Override public void init(Config conf) { this.conf = conf; } /** {@inheritDoc} */ @Override public Config getConf() { return conf; } /*************************************************/ /** AuthenticationToken Resolution Support **/ /*************************************************/ /** {@inheritDoc} */ @Override public AuthenticationToken resolveAuthenticationToken(HttpServletRequest request) { if (conf.hasPath("principal-header")) { String principal = conf.getString("principal-header"); if (principal != null && principal.trim().length() > 0) { return new PrincipalAuthenticationToken(principal); } } // No principal resolved return null; } /*************************************************/ /** Authentication Support **/ /*************************************************/ /** {@inheritDoc} */ @Override public void authenticate(AuthenticationToken token) throws AuthenticationException { if (token == null || token.getPrincipal() == null) { throw new AuthenticationException("No principal defined"); } } /*************************************************/ /** Client Verification Support **/ /*************************************************/ /** {@inheritDoc} */ @Override public void verifyClient(Object principal, String id) throws ClientVerificationException { if (principal == null || id == null) { throw new ClientVerificationException("Client verification error"); } if (!principal.toString().equalsIgnoreCase(id)) { throw new ClientVerificationException("Client verification error. " + principal + " not identical to " + id); } } /*************************************************/ /** Support classes **/ /*************************************************/ /** * An authentication token that defines a principal but no credentials */ public static class PrincipalAuthenticationToken implements AuthenticationToken { private String principal; /** No-arg constructor */ public PrincipalAuthenticationToken() { } /** * Constructor * @param principal the principal */ public PrincipalAuthenticationToken(String principal) { this.principal = principal; } /** {@inheritDoc} */ @Override public Object getPrincipal() { return principal; } /** {@inheritDoc} */ @Override public Object getCredentials() { return null; } } }