001/** 002 * Copyright (C) 2009 "Darwin V. Felix" <darwinfelix@users.sourceforge.net> 003 * 004 * This library is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU Lesser General Public 006 * License as published by the Free Software Foundation; either 007 * version 2.1 of the License, or (at your option) any later version. 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this library; if not, write to the Free Software 016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 017 */ 018 019package net.sourceforge.spnego; 020 021import java.security.Principal; 022 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpServletRequestWrapper; 025 026import net.sourceforge.spnego.SpnegoHttpFilter.Constants; 027 028import org.ietf.jgss.GSSCredential; 029 030/** 031 * Wrap ServletRequest so we can do our own handling of the 032 * principal and auth types. 033 * 034 * <p>Also, see the documentation on the {@link DelegateServletRequest} class.</p> 035 * 036 * <p>Finally, a credential delegation example can be found on 037 * <a href="http://spnego.sourceforge.net" target="_blank">http://spnego.sourceforge.net</a> 038 * </p> 039 * 040 * @author Darwin V. Felix 041 * 042 */ 043final class SpnegoHttpServletRequest extends HttpServletRequestWrapper 044 implements DelegateServletRequest, SpnegoAccessControl { 045 046 private static final String MESSAGE_UNSUPPORTED = 047 "User Access Control has NOT been defined or is NOT supported."; 048 049 /** Client Principal. */ 050 private final transient SpnegoPrincipal principal; 051 052 /** authZ framework interface. */ 053 private final transient UserAccessControl accessControl; 054 055 /** 056 * Creates Servlet Request specifying KerberosPrincipal of user. 057 * 058 * @param request 059 * @param spnegoPrincipal 060 */ 061 SpnegoHttpServletRequest(final HttpServletRequest request 062 , final SpnegoPrincipal spnegoPrincipal) { 063 064 this(request, spnegoPrincipal, null); 065 } 066 067 /** 068 * Creates Servlet Request specifying KerberosPrincipal of user 069 * and a specified User Access Control (authZ). 070 * @param request 071 * @param spnegoPrincipal 072 * @param userAccessControl 073 */ 074 SpnegoHttpServletRequest(final HttpServletRequest request 075 , final SpnegoPrincipal spnegoPrincipal 076 , final UserAccessControl userAccessControl) { 077 078 super(request); 079 080 this.principal = spnegoPrincipal; 081 this.accessControl = userAccessControl; 082 } 083 084 /** 085 * Returns "Negotiate" or "Basic" else default auth type. 086 * 087 * @see javax.servlet.http.HttpServletRequest#getAuthType() 088 */ 089 @Override 090 public String getAuthType() { 091 092 final String authType; 093 final String header = this.getHeader(Constants.AUTHZ_HEADER); 094 095 if (null == header) { 096 authType = super.getAuthType(); 097 098 } else if (header.startsWith(Constants.NEGOTIATE_HEADER)) { 099 authType = Constants.NEGOTIATE_HEADER; 100 101 } else if (header.startsWith(Constants.BASIC_HEADER)) { 102 authType = Constants.BASIC_HEADER; 103 104 } else { 105 authType = super.getAuthType(); 106 } 107 108 return authType; 109 } 110 111 /* 112 * (non-Javadoc) 113 * @see net.sourceforge.spnego.DelegateServletRequest#getDelegatedCredential() 114 */ 115 @Override 116 public GSSCredential getDelegatedCredential() { 117 return this.principal.getDelegatedCredential(); 118 } 119 120 /** 121 * Returns authenticated username (sans domain/realm) else default username. 122 * 123 * @see javax.servlet.http.HttpServletRequest#getRemoteUser() 124 */ 125 @Override 126 public String getRemoteUser() { 127 128 if (null == this.principal) { 129 return super.getRemoteUser(); 130 131 } else { 132 final String[] username = this.principal.getName().split("@", 2); 133 return username[0]; 134 } 135 } 136 137 /** 138 * Returns KerberosPrincipal of user. 139 * 140 * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() 141 */ 142 @Override 143 public Principal getUserPrincipal() { 144 return this.principal; 145 } 146 147 /* 148 * (non-Javadoc) 149 * @see net.sourceforge.spnego.SpnegoAccessControl#anyRole(java.lang.String[]) 150 */ 151 @Override 152 public boolean anyRole(final String... roles) { 153 if (null == this.accessControl) { 154 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 155 } 156 157 return this.accessControl.anyRole(this.getRemoteUser(), roles); 158 } 159 160 /* 161 * (non-Javadoc) 162 * @see net.sourceforge.spnego.SpnegoAccessControl#hasRole(java.lang.String) 163 */ 164 @Override 165 public boolean hasRole(final String role) { 166 if (null == this.accessControl) { 167 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 168 } 169 170 return this.accessControl.hasRole(this.getRemoteUser(), role); 171 } 172 173 /* 174 * (non-Javadoc) 175 * @see net.sourceforge.spnego.SpnegoAccessControl#hasRole(java.lang.String, java.lang.String[]) 176 */ 177 @Override 178 public boolean hasRole(final String featureX, final String... featureYs) { 179 // assert 180 if (null == this.accessControl) { 181 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 182 } 183 184 return this.accessControl.hasRole(this.getRemoteUser(), featureX, featureYs); 185 } 186 187 /* 188 * (non-Javadoc) 189 * @see net.sourceforge.spnego.SpnegoAccessControl#anyAccess(java.lang.String[]) 190 */ 191 @Override 192 public boolean anyAccess(final String... resources) { 193 if (null == this.accessControl) { 194 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 195 } 196 197 return this.accessControl.anyAccess(this.getRemoteUser(), resources); 198 } 199 200 /* 201 * (non-Javadoc) 202 * @see net.sourceforge.spnego.SpnegoAccessControl#hasAccess(java.lang.String) 203 */ 204 @Override 205 public boolean hasAccess(final String resource) { 206 // assert 207 if (null == this.accessControl) { 208 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 209 } 210 211 return this.accessControl.hasAccess(this.getRemoteUser(), resource); 212 } 213 214 /* 215 * (non-Javadoc) 216 * @see net.sourceforge.spnego.SpnegoAccessControl#hasAccess(java.lang.String, java.lang.String[]) 217 */ 218 @Override 219 public boolean hasAccess(final String resourceX, final String... resourceYs) { 220 // assert 221 if (null == this.accessControl) { 222 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 223 } 224 225 return this.accessControl.hasAccess(this.getRemoteUser(), resourceX, resourceYs); 226 } 227 228 /* 229 * (non-Javadoc) 230 * @see net.sourceforge.spnego.SpnegoAccessControl#getUserInfo() 231 */ 232 @Override 233 public UserInfo getUserInfo() { 234 // assert 235 if (null == this.accessControl) { 236 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 237 } 238 239 final UserInfo userInfo = this.accessControl.getUserInfo(this.getRemoteUser()); 240 241 if (null == userInfo) { 242 throw new UnsupportedOperationException("UserInfo was NULL and/or not configured"); 243 } else { 244 return userInfo; 245 } 246 } 247 248 /* 249 * (non-Javadoc) 250 * @see javax.servlet.http.HttpServletRequestWrapper#isUserInRole(java.lang.String) 251 */ 252 @Override 253 public boolean isUserInRole(final String role) { 254 if (null == this.accessControl) { 255 throw new UnsupportedOperationException(MESSAGE_UNSUPPORTED); 256 } 257 258 return this.accessControl.hasRole(this.getRemoteUser(), role); 259 } 260}