1 /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 package org.acegisecurity.wrapper;
17
18 import org.acegisecurity.Authentication;
19 import org.acegisecurity.AuthenticationTrustResolver;
20 import org.acegisecurity.AuthenticationTrustResolverImpl;
21
22 import org.acegisecurity.context.SecurityContextHolder;
23
24 import org.acegisecurity.userdetails.UserDetails;
25 import org.acegisecurity.util.PortResolver;
26
27 import java.security.Principal;
28
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletRequestWrapper;
31
32
33 /**
34 * An Acegi Security-aware <code>HttpServletRequestWrapper</code>, which uses the
35 * <code>SecurityContext</code>-defined <code>Authentication</code> object for {@link
36 * SecurityContextHolderAwareRequestWrapper#isUserInRole(java.lang.String)} and {@link
37 * javax.servlet.http.HttpServletRequestWrapper#getRemoteUser()} responses.
38 *
39 * @author Orlando Garcia Carmona
40 * @author Ben Alex
41 * @version $Id: SecurityContextHolderAwareRequestWrapper.java 1859 2007-05-24 23:20:40Z vishalpuri $
42 */
43 public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequestWrapper {
44 //~ Instance fields ================================================================================================
45
46 private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
47
48 //~ Constructors ===================================================================================================
49
50 public SecurityContextHolderAwareRequestWrapper(HttpServletRequest request, PortResolver portResolver) {
51 super(request);
52 }
53
54 //~ Methods ========================================================================================================
55
56 /**
57 * Obtain the current active <code>Authentication</code>
58 *
59 * @return the authentication object or <code>null</code>
60 */
61 private Authentication getAuthentication() {
62 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
63
64 if (!authenticationTrustResolver.isAnonymous(auth)) {
65 return auth;
66 }
67
68 return null;
69 }
70
71 /**
72 * Returns the principal's name, as obtained from the <code>SecurityContextHolder</code>. Properly handles
73 * both <code>String</code>-based and <code>UserDetails</code>-based principals.
74 *
75 * @return the username or <code>null</code> if unavailable
76 */
77 public String getRemoteUser() {
78 Authentication auth = getAuthentication();
79
80 if ((auth == null) || (auth.getPrincipal() == null)) {
81 return null;
82 }
83
84 if (auth.getPrincipal() instanceof UserDetails) {
85 return ((UserDetails) auth.getPrincipal()).getUsername();
86 }
87
88 return auth.getPrincipal().toString();
89 }
90
91 /**
92 * Returns the <code>Authentication</code> (which is a subclass of <code>Principal</code>), or
93 * <code>null</code> if unavailable.
94 *
95 * @return the <code>Authentication</code>, or <code>null</code>
96 */
97 public Principal getUserPrincipal() {
98 Authentication auth = getAuthentication();
99
100 if ((auth == null) || (auth.getPrincipal() == null)) {
101 return null;
102 }
103
104 return auth;
105 }
106
107 private boolean isGranted(String role) {
108 Authentication auth = getAuthentication();
109
110 if ((auth == null) || (auth.getPrincipal() == null) || (auth.getAuthorities() == null)) {
111 return false;
112 }
113
114 for (int i = 0; i < auth.getAuthorities().length; i++) {
115 if (role.equals(auth.getAuthorities()[i].getAuthority())) {
116 return true;
117 }
118 }
119
120 return false;
121 }
122
123 /**
124 * Simple searches for an exactly matching {@link org.acegisecurity.GrantedAuthority#getAuthority()}.<p>Will
125 * always return <code>false</code> if the <code>SecurityContextHolder</code> contains an
126 * <code>Authentication</code> with <code>null</code><code>principal</code> and/or <code>GrantedAuthority[]</code>
127 * objects.</p>
128 *
129 * @param role the <code>GrantedAuthority</code><code>String</code> representation to check for
130 *
131 * @return <code>true</code> if an <b>exact</b> (case sensitive) matching granted authority is located,
132 * <code>false</code> otherwise
133 */
134 public boolean isUserInRole(String role) {
135 return isGranted(role);
136 }
137 }