001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.web.mgt; 020 021import org.apache.shiro.mgt.DefaultSubjectFactory; 022import org.apache.shiro.mgt.SecurityManager; 023import org.apache.shiro.session.Session; 024import org.apache.shiro.subject.PrincipalCollection; 025import org.apache.shiro.subject.Subject; 026import org.apache.shiro.subject.SubjectContext; 027import org.apache.shiro.web.subject.WebSubjectContext; 028import org.apache.shiro.web.subject.support.WebDelegatingSubject; 029 030import javax.servlet.ServletRequest; 031import javax.servlet.ServletResponse; 032 033import org.apache.shiro.web.subject.WebSubject; 034 035/** 036 * A {@code SubjectFactory} implementation that creates {@link WebDelegatingSubject} instances. 037 * <p/> 038 * {@code WebDelegatingSubject} instances are required if Request/Response objects are to be maintained across 039 * threads when using the {@code Subject} {@link Subject#associateWith(java.util.concurrent.Callable) createCallable} 040 * and {@link Subject#associateWith(Runnable) createRunnable} methods. 041 * 042 * @since 1.0 043 */ 044public class DefaultWebSubjectFactory extends DefaultSubjectFactory { 045 046 public DefaultWebSubjectFactory() { 047 super(); 048 } 049 050 public Subject createSubject(SubjectContext context) { 051 //SHIRO-646 052 //Check if the existing subject is NOT a WebSubject. If it isn't, then call super.createSubject instead. 053 //Creating a WebSubject from a non-web Subject will cause the ServletRequest and ServletResponse to be null, 054 // which wil fail when creating a session. 055 boolean isNotBasedOnWebSubject = context.getSubject() != null && !(context.getSubject() instanceof WebSubject); 056 if (!(context instanceof WebSubjectContext) || isNotBasedOnWebSubject) { 057 return super.createSubject(context); 058 } 059 WebSubjectContext wsc = (WebSubjectContext) context; 060 SecurityManager securityManager = wsc.resolveSecurityManager(); 061 Session session = wsc.resolveSession(); 062 boolean sessionEnabled = wsc.isSessionCreationEnabled(); 063 PrincipalCollection principals = wsc.resolvePrincipals(); 064 boolean authenticated = wsc.resolveAuthenticated(); 065 String host = wsc.resolveHost(); 066 ServletRequest request = wsc.resolveServletRequest(); 067 ServletResponse response = wsc.resolveServletResponse(); 068 069 return new WebDelegatingSubject(principals, authenticated, host, session, sessionEnabled, 070 request, response, securityManager); 071 } 072 073 /** 074 * @deprecated since 1.2 - override {@link #createSubject(org.apache.shiro.subject.SubjectContext)} directly if you 075 * need to instantiate a custom {@link Subject} class. 076 */ 077 @Deprecated 078 protected Subject newSubjectInstance(PrincipalCollection principals, boolean authenticated, 079 String host, Session session, 080 ServletRequest request, ServletResponse response, 081 SecurityManager securityManager) { 082 return new WebDelegatingSubject(principals, authenticated, host, session, true, 083 request, response, securityManager); 084 } 085}