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 module hunt.shiro.subject.support.DefaultSubjectContext; 20 21 import hunt.shiro.Exceptions; 22 import hunt.shiro.SecurityUtils; 23 import hunt.shiro.authc.AuthenticationInfo; 24 import hunt.shiro.authc.AuthenticationToken; 25 import hunt.shiro.authc.HostAuthenticationToken; 26 import hunt.shiro.mgt.SecurityManager; 27 import hunt.shiro.session.Session; 28 import hunt.shiro.subject.PrincipalCollection; 29 import hunt.shiro.subject.Subject; 30 import hunt.shiro.subject.SubjectContext; 31 import hunt.shiro.util.MapContext; 32 // // import hunt.shiro.util.StringUtils; 33 import hunt.logging.Logger; 34 35 import hunt.Boolean; 36 import hunt.collection.Map; 37 import hunt.String; 38 import hunt.util.Common; 39 40 import std.array; 41 import std.traits; 42 43 /** 44 * Default implementation of the {@link SubjectContext} interface. Note that the getters and setters are not 45 * simple pass-through methods to an underlying attribute; the getters will employ numerous heuristics to acquire 46 * their data attribute as best as possible (for example, if {@link #getPrincipals} is invoked, if the principals aren't 47 * in the backing map, it might check to see if there is a subject or session in the map and attempt to acquire the 48 * principals from those objects). 49 * 50 */ 51 class DefaultSubjectContext : MapContext, SubjectContext { 52 53 private enum string SECURITY_MANAGER = fullyQualifiedName!(DefaultSubjectContext) ~ ".SECURITY_MANAGER"; 54 55 private enum string SESSION_ID = fullyQualifiedName!(DefaultSubjectContext) ~ ".SESSION_ID"; 56 57 private enum string AUTHENTICATION_TOKEN = fullyQualifiedName!(DefaultSubjectContext) ~ ".AUTHENTICATION_TOKEN"; 58 59 private enum string AUTHENTICATION_INFO = fullyQualifiedName!(DefaultSubjectContext) ~ ".AUTHENTICATION_INFO"; 60 61 private enum string SUBJECT = fullyQualifiedName!(DefaultSubjectContext) ~ ".SUBJECT"; 62 63 private enum string PRINCIPALS = fullyQualifiedName!(DefaultSubjectContext) ~ ".PRINCIPALS"; 64 65 private enum string SESSION = fullyQualifiedName!(DefaultSubjectContext) ~ ".SESSION"; 66 67 private enum string AUTHENTICATED = fullyQualifiedName!(DefaultSubjectContext) ~ ".AUTHENTICATED"; 68 69 private enum string HOST = fullyQualifiedName!(DefaultSubjectContext) ~ ".HOST"; 70 71 enum string SESSION_CREATION_ENABLED = fullyQualifiedName!(DefaultSubjectContext) ~ ".SESSION_CREATION_ENABLED"; 72 73 /** 74 * The session key that is used to store subject principals. 75 */ 76 enum string PRINCIPALS_SESSION_KEY = fullyQualifiedName!(DefaultSubjectContext) ~ "_PRINCIPALS_SESSION_KEY"; 77 78 /** 79 * The session key that is used to store whether or not the user is authenticated. 80 */ 81 enum string AUTHENTICATED_SESSION_KEY = fullyQualifiedName!(DefaultSubjectContext) ~ "_AUTHENTICATED_SESSION_KEY"; 82 83 84 85 this() { 86 super(); 87 } 88 89 this(SubjectContext ctx) { 90 super(cast(Map!(string, Object))ctx); 91 } 92 93 SecurityManager getSecurityManager() { 94 return getTypedValue!SecurityManager(SECURITY_MANAGER); 95 } 96 97 void setSecurityManager(SecurityManager securityManager) { 98 nullSafePut(SECURITY_MANAGER, cast(Object)securityManager); 99 } 100 101 SecurityManager resolveSecurityManager() { 102 SecurityManager securityManager = getSecurityManager(); 103 if (securityManager is null) { 104 version(HUNT_AUTH_DEBUG) { 105 warningf("No SecurityManager available in subject context map. " ~ 106 "Falling back to SecurityUtils.getSecurityManager() lookup."); 107 } 108 // try { 109 // securityManager = SecurityUtils.getSecurityManager(); 110 // } catch (UnavailableSecurityManagerException e) { 111 // version(HUNT_AUTH_DEBUG) { 112 // warningf("No SecurityManager available via SecurityUtils." ~ 113 // " Heuristics exhausted. The reason is: %s", e.msg); 114 // } 115 // version(HUNT_SHIRO_DEBUG) { 116 // warning(e); 117 // } 118 // } 119 } 120 return securityManager; 121 } 122 123 string getSessionId() { 124 String s = getTypedValue!String(SESSION_ID); 125 if(s !is null) 126 return getTypedValue!String(SESSION_ID).value; 127 else 128 return null; 129 } 130 131 void setSessionId(string sessionId) { 132 nullSafePut(SESSION_ID, new String(sessionId)); 133 } 134 135 Subject getSubject() { 136 return getTypedValue!Subject(SUBJECT); 137 } 138 139 void setSubject(Subject subject) { 140 nullSafePut(SUBJECT, cast(Object)subject); 141 } 142 143 PrincipalCollection getPrincipals() { 144 return getTypedValue!PrincipalCollection(PRINCIPALS); 145 } 146 147 private static bool isEmpty(PrincipalCollection pc) { 148 return pc is null || pc.isEmpty(); 149 } 150 151 void setPrincipals(PrincipalCollection principals) { 152 if (!isEmpty(principals)) { 153 put(PRINCIPALS, cast(Object)principals); 154 } 155 } 156 157 PrincipalCollection resolvePrincipals() { 158 PrincipalCollection principals = getPrincipals(); 159 160 if (isEmpty(principals)) { 161 //check to see if they were just authenticated: 162 AuthenticationInfo info = getAuthenticationInfo(); 163 if (info !is null) { 164 principals = info.getPrincipals(); 165 } 166 } 167 168 if (isEmpty(principals)) { 169 Subject subject = getSubject(); 170 if (subject !is null) { 171 principals = subject.getPrincipals(); 172 } 173 } 174 175 if (isEmpty(principals)) { 176 //try the session: 177 Session session = resolveSession(); 178 if (session !is null) { 179 principals = cast(PrincipalCollection) session.getAttribute(new String(PRINCIPALS_SESSION_KEY)); 180 } 181 } 182 183 return principals; 184 } 185 186 187 Session getSession() { 188 return getTypedValue!Session(SESSION); 189 } 190 191 void setSession(Session session) { 192 nullSafePut(SESSION, cast(Object)session); 193 } 194 195 Session resolveSession() { 196 Session session = getSession(); 197 if (session is null) { 198 //try the Subject if it exists: 199 Subject existingSubject = getSubject(); 200 if (existingSubject !is null) { 201 session = existingSubject.getSession(false); 202 } 203 } 204 return session; 205 } 206 207 bool isSessionCreationEnabled() { 208 Boolean val = getTypedValue!(Boolean)(SESSION_CREATION_ENABLED); 209 return val is null || val.value; 210 } 211 212 void setSessionCreationEnabled(bool enabled) { 213 nullSafePut(SESSION_CREATION_ENABLED, new Boolean(enabled)); 214 } 215 216 bool isAuthenticated() { 217 Boolean authc = getTypedValue!(Boolean)(AUTHENTICATED); 218 return authc !is null && authc.value; 219 } 220 221 void setAuthenticated(bool authc) { 222 put(AUTHENTICATED, new Boolean(authc)); 223 } 224 225 bool resolveAuthenticated() { 226 Boolean authc = getTypedValue!Boolean(AUTHENTICATED); 227 if (authc is null) { 228 //see if there is an AuthenticationInfo object. If so, the very presence of one indicates a successful 229 //authentication attempt: 230 AuthenticationInfo info = getAuthenticationInfo(); 231 authc = new Boolean(info !is null); 232 } 233 234 if (!authc.value) { 235 //fall back to a session check: 236 Session session = resolveSession(); 237 if (session !is null) { 238 Boolean sessionAuthc = cast(Boolean) session.getAttribute(new String(AUTHENTICATED_SESSION_KEY)); 239 return sessionAuthc !is null && sessionAuthc.value; 240 } 241 } 242 243 return authc.value; 244 } 245 246 AuthenticationInfo getAuthenticationInfo() { 247 return getTypedValue!AuthenticationInfo(AUTHENTICATION_INFO); 248 } 249 250 void setAuthenticationInfo(AuthenticationInfo info) { 251 nullSafePut(AUTHENTICATION_INFO, cast(Object)info); 252 } 253 254 AuthenticationToken getAuthenticationToken() { 255 return getTypedValue!AuthenticationToken(AUTHENTICATION_TOKEN); 256 } 257 258 void setAuthenticationToken(AuthenticationToken token) { 259 nullSafePut(AUTHENTICATION_TOKEN, cast(Object)token); 260 } 261 262 string getHost() { 263 String s = getTypedValue!String(HOST); 264 if(s is null) 265 return null; 266 else 267 return s.value; 268 } 269 270 void setHost(string host) { 271 if (!host.empty()) { 272 put(HOST, new String(host)); 273 } 274 } 275 276 string resolveHost() { 277 string host = getHost(); 278 279 if (host is null) { 280 //check to see if there is an AuthenticationToken from which to retrieve it: 281 AuthenticationToken token = getAuthenticationToken(); 282 HostAuthenticationToken hat = cast(HostAuthenticationToken) token; 283 if (hat !is null) { 284 host = hat.getHost(); 285 } 286 } 287 288 if (host is null) { 289 Session session = resolveSession(); 290 if (session !is null) { 291 host = session.getHost(); 292 } 293 } 294 295 return host; 296 } 297 298 }