001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.core.impl.authentication; 017 018import java.util.Map; 019 020import org.apache.avalon.framework.context.Context; 021import org.apache.avalon.framework.context.ContextException; 022import org.apache.avalon.framework.context.Contextualizable; 023import org.apache.cocoon.components.ContextHelper; 024import org.apache.cocoon.environment.ObjectModelHelper; 025import org.apache.cocoon.environment.Redirector; 026import org.apache.commons.lang3.StringUtils; 027 028import org.ametys.core.authentication.AbstractCredentialProvider; 029import org.ametys.core.authentication.NonBlockingCredentialProvider; 030import org.ametys.core.user.UserIdentity; 031 032/** 033 * This manager gets the credentials given by a J2EE filter authentication.<br> 034 * The filter must set the 'remote user' header into the request.<br> 035 * <br> 036 * This manager can not get the password of the connected user: the user is 037 * already authentified. This manager should not be associated with an 038 * <code>AuthenticableBaseUser</code> 039 */ 040public class RemoteUserCredentialProvider extends AbstractCredentialProvider implements NonBlockingCredentialProvider, Contextualizable 041{ 042 /** Name of the parameter holding the authentication realm */ 043 private static final String __PARAM_REALM = "runtime.authentication.remote.realm"; 044 045 /** Name of the parameter holding the header name */ 046 private static final String __PARAM_HEADER_NAME = "runtime.authentication.remote.header.name"; 047 048 /** The realm */ 049 protected String _realm; 050 051 /** The header name */ 052 protected String _headerName; 053 054 private Context _context; 055 056 @Override 057 public void contextualize(Context context) throws ContextException 058 { 059 _context = context; 060 } 061 062 @Override 063 public void init(String id, String cpModelId, Map<String, Object> paramValues, String label) throws Exception 064 { 065 super.init(id, cpModelId, paramValues, label); 066 _realm = (String) paramValues.get(__PARAM_REALM); 067 _headerName = (String) paramValues.get(__PARAM_HEADER_NAME); 068 } 069 070 @Override 071 public boolean nonBlockingIsStillConnected(UserIdentity userIdentity, Redirector redirector) throws Exception 072 { 073 // this manager is always valid 074 return true; 075 } 076 077 @Override 078 public boolean nonBlockingGrantAnonymousRequest() 079 { 080 // this implementation does not have any particular request 081 // to take into account 082 return false; 083 } 084 085 @Override 086 public UserIdentity nonBlockingGetUserIdentity(Redirector redirector) throws Exception 087 { 088 Map objectModel = ContextHelper.getObjectModel(_context); 089 String remoteLogin = ObjectModelHelper.getRequest(objectModel).getHeader(_headerName); 090 if (remoteLogin == null) 091 { 092 getLogger().error("Remote User is null! Missing filter?"); 093 return null; 094 } 095 096 if (StringUtils.isNotBlank(_realm)) 097 { 098 int begin = remoteLogin.indexOf("\\"); 099 if (begin <= 0) 100 { 101 /* Domain authentication but non compliant */ 102 getLogger().error("Remote User '{}' does not match realm\\login", remoteLogin); 103 return null; 104 } 105 106 String userLogin = remoteLogin.substring(begin + 1); 107 String userRealm = remoteLogin.substring(0, begin); 108 109 if (!_realm.equals(userRealm)) 110 { 111 getLogger().error("Remote user realm '{}' does not match application realm '{}'", userRealm, _realm); 112 return null; 113 } 114 115 return new UserIdentity(userLogin, null); 116 } 117 else 118 { 119 return new UserIdentity(remoteLogin, null); 120 } 121 122 123 } 124 125 @Override 126 public void nonBlockingUserNotAllowed(Redirector redirector) 127 { 128 // nothing to do 129 } 130 131 @Override 132 public void nonBlockingUserAllowed(UserIdentity userIdentity, Redirector redirector) 133 { 134 // nothing to do 135 } 136}