View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.subject.support;
20  
21  import org.apache.shiro.SecurityUtils;
22  import org.apache.shiro.UnavailableSecurityManagerException;
23  import org.apache.shiro.authc.AuthenticationInfo;
24  import org.apache.shiro.authc.AuthenticationToken;
25  import org.apache.shiro.authc.HostAuthenticationToken;
26  import org.apache.shiro.mgt.SecurityManager;
27  import org.apache.shiro.session.Session;
28  import org.apache.shiro.subject.PrincipalCollection;
29  import org.apache.shiro.subject.Subject;
30  import org.apache.shiro.subject.SubjectContext;
31  import org.apache.shiro.util.CollectionUtils;
32  import org.apache.shiro.util.MapContext;
33  import org.apache.shiro.util.StringUtils;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import java.io.Serializable;
38  
39  /**
40   * Default implementation of the {@link SubjectContext} interface.  Note that the getters and setters are not
41   * simple pass-through methods to an underlying attribute;  the getters will employ numerous heuristics to acquire
42   * their data attribute as best as possible (for example, if {@link #getPrincipals} is invoked, if the principals aren't
43   * in the backing map, it might check to see if there is a subject or session in the map and attempt to acquire the
44   * principals from those objects).
45   *
46   * @since 1.0
47   */
48  public class DefaultSubjectContext extends MapContext implements SubjectContext {
49  
50      private static final String SECURITY_MANAGER = DefaultSubjectContext.class.getName() + ".SECURITY_MANAGER";
51  
52      private static final String SESSION_ID = DefaultSubjectContext.class.getName() + ".SESSION_ID";
53  
54      private static final String AUTHENTICATION_TOKEN = DefaultSubjectContext.class.getName() + ".AUTHENTICATION_TOKEN";
55  
56      private static final String AUTHENTICATION_INFO = DefaultSubjectContext.class.getName() + ".AUTHENTICATION_INFO";
57  
58      private static final String SUBJECT = DefaultSubjectContext.class.getName() + ".SUBJECT";
59  
60      private static final String PRINCIPALS = DefaultSubjectContext.class.getName() + ".PRINCIPALS";
61  
62      private static final String SESSION = DefaultSubjectContext.class.getName() + ".SESSION";
63  
64      private static final String AUTHENTICATED = DefaultSubjectContext.class.getName() + ".AUTHENTICATED";
65  
66      private static final String HOST = DefaultSubjectContext.class.getName() + ".HOST";
67  
68      public static final String SESSION_CREATION_ENABLED = DefaultSubjectContext.class.getName() + ".SESSION_CREATION_ENABLED";
69  
70      /**
71       * The session key that is used to store subject principals.
72       */
73      public static final String PRINCIPALS_SESSION_KEY = DefaultSubjectContext.class.getName() + "_PRINCIPALS_SESSION_KEY";
74  
75      /**
76       * The session key that is used to store whether or not the user is authenticated.
77       */
78      public static final String AUTHENTICATED_SESSION_KEY = DefaultSubjectContext.class.getName() + "_AUTHENTICATED_SESSION_KEY";
79  
80      private static final transient Logger log = LoggerFactory.getLogger(DefaultSubjectContext.class);
81  
82      public DefaultSubjectContext() {
83          super();
84      }
85  
86      public DefaultSubjectContext(SubjectContext ctx) {
87          super(ctx);
88      }
89  
90      public SecurityManager getSecurityManager() {
91          return getTypedValue(SECURITY_MANAGER, SecurityManager.class);
92      }
93  
94      public void setSecurityManager(SecurityManager securityManager) {
95          nullSafePut(SECURITY_MANAGER, securityManager);
96      }
97  
98      public SecurityManager resolveSecurityManager() {
99          SecurityManager securityManager = getSecurityManager();
100         if (securityManager == null) {
101             if (log.isDebugEnabled()) {
102                 log.debug("No SecurityManager available in subject context map.  " +
103                         "Falling back to SecurityUtils.getSecurityManager() lookup.");
104             }
105             try {
106                 securityManager = SecurityUtils.getSecurityManager();
107             } catch (UnavailableSecurityManagerException e) {
108                 if (log.isDebugEnabled()) {
109                     log.debug("No SecurityManager available via SecurityUtils.  Heuristics exhausted.", e);
110                 }
111             }
112         }
113         return securityManager;
114     }
115 
116     public Serializable getSessionId() {
117         return getTypedValue(SESSION_ID, Serializable.class);
118     }
119 
120     public void setSessionId(Serializable sessionId) {
121         nullSafePut(SESSION_ID, sessionId);
122     }
123 
124     public Subject getSubject() {
125         return getTypedValue(SUBJECT, Subject.class);
126     }
127 
128     public void setSubject(Subject subject) {
129         nullSafePut(SUBJECT, subject);
130     }
131 
132     public PrincipalCollection getPrincipals() {
133         return getTypedValue(PRINCIPALS, PrincipalCollection.class);
134     }
135 
136     public void setPrincipals(PrincipalCollection principals) {
137         if (!CollectionUtils.isEmpty(principals)) {
138             put(PRINCIPALS, principals);
139         }
140     }
141 
142     public PrincipalCollection resolvePrincipals() {
143         PrincipalCollection principals = getPrincipals();
144 
145         if (CollectionUtils.isEmpty(principals)) {
146             //check to see if they were just authenticated:
147             AuthenticationInfo info = getAuthenticationInfo();
148             if (info != null) {
149                 principals = info.getPrincipals();
150             }
151         }
152 
153         if (CollectionUtils.isEmpty(principals)) {
154             Subject subject = getSubject();
155             if (subject != null) {
156                 principals = subject.getPrincipals();
157             }
158         }
159 
160         if (CollectionUtils.isEmpty(principals)) {
161             //try the session:
162             Session session = resolveSession();
163             if (session != null) {
164                 principals = (PrincipalCollection) session.getAttribute(PRINCIPALS_SESSION_KEY);
165             }
166         }
167 
168         return principals;
169     }
170 
171 
172     public Session getSession() {
173         return getTypedValue(SESSION, Session.class);
174     }
175 
176     public void setSession(Session session) {
177         nullSafePut(SESSION, session);
178     }
179 
180     public Session resolveSession() {
181         Session session = getSession();
182         if (session == null) {
183             //try the Subject if it exists:
184             Subject existingSubject = getSubject();
185             if (existingSubject != null) {
186                 session = existingSubject.getSession(false);
187             }
188         }
189         return session;
190     }
191 
192     public boolean isSessionCreationEnabled() {
193         Boolean val = getTypedValue(SESSION_CREATION_ENABLED, Boolean.class);
194         return val == null || val;
195     }
196 
197     public void setSessionCreationEnabled(boolean enabled) {
198         nullSafePut(SESSION_CREATION_ENABLED, enabled);
199     }
200 
201     public boolean isAuthenticated() {
202         Boolean authc = getTypedValue(AUTHENTICATED, Boolean.class);
203         return authc != null && authc;
204     }
205 
206     public void setAuthenticated(boolean authc) {
207         put(AUTHENTICATED, authc);
208     }
209 
210     public boolean resolveAuthenticated() {
211         Boolean authc = getTypedValue(AUTHENTICATED, Boolean.class);
212         if (authc == null) {
213             //see if there is an AuthenticationInfo object.  If so, the very presence of one indicates a successful
214             //authentication attempt:
215             AuthenticationInfo info = getAuthenticationInfo();
216             authc = info != null;
217         }
218         if (!authc) {
219             //fall back to a session check:
220             Session session = resolveSession();
221             if (session != null) {
222                 Boolean sessionAuthc = (Boolean) session.getAttribute(AUTHENTICATED_SESSION_KEY);
223                 authc = sessionAuthc != null && sessionAuthc;
224             }
225         }
226 
227         return authc;
228     }
229 
230     public AuthenticationInfo getAuthenticationInfo() {
231         return getTypedValue(AUTHENTICATION_INFO, AuthenticationInfo.class);
232     }
233 
234     public void setAuthenticationInfo(AuthenticationInfo info) {
235         nullSafePut(AUTHENTICATION_INFO, info);
236     }
237 
238     public AuthenticationToken getAuthenticationToken() {
239         return getTypedValue(AUTHENTICATION_TOKEN, AuthenticationToken.class);
240     }
241 
242     public void setAuthenticationToken(AuthenticationToken token) {
243         nullSafePut(AUTHENTICATION_TOKEN, token);
244     }
245 
246     public String getHost() {
247         return getTypedValue(HOST, String.class);
248     }
249 
250     public void setHost(String host) {
251         if (StringUtils.hasText(host)) {
252             put(HOST, host);
253         }
254     }
255 
256     public String resolveHost() {
257         String host = getHost();
258 
259         if (host == null) {
260             //check to see if there is an AuthenticationToken from which to retrieve it:
261             AuthenticationToken token = getAuthenticationToken();
262             if (token instanceof HostAuthenticationToken) {
263                 host = ((HostAuthenticationToken) token).getHost();
264             }
265         }
266 
267         if (host == null) {
268             Session session = resolveSession();
269             if (session != null) {
270                 host = session.getHost();
271             }
272         }
273 
274         return host;
275     }
276 }