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.web.subject; 20 21 import org.apache.shiro.SecurityUtils; 22 import org.apache.shiro.mgt.SecurityManager; 23 import org.apache.shiro.subject.Subject; 24 import org.apache.shiro.subject.SubjectContext; 25 import org.apache.shiro.web.subject.support.DefaultWebSubjectContext; 26 import org.apache.shiro.web.util.RequestPairSource; 27 28 import javax.servlet.ServletRequest; 29 import javax.servlet.ServletResponse; 30 31 /** 32 * A {@code WebSubject} represents a Subject instance that was acquired as a result of an incoming 33 * {@link ServletRequest}. 34 * 35 * @since 1.0 36 */ 37 public interface WebSubject extends Subject, RequestPairSource { 38 39 /** 40 * Returns the {@code ServletRequest} accessible when the Subject instance was created. 41 * 42 * @return the {@code ServletRequest} accessible when the Subject instance was created. 43 */ 44 ServletRequest getServletRequest(); 45 46 /** 47 * Returns the {@code ServletResponse} accessible when the Subject instance was created. 48 * 49 * @return the {@code ServletResponse} accessible when the Subject instance was created. 50 */ 51 ServletResponse getServletResponse(); 52 53 /** 54 * A {@code WebSubject.Builder} performs the same function as a {@link Subject.Builder Subject.Builder}, but 55 * additionally ensures that the Servlet request/response pair that is triggering the Subject instance's creation 56 * is retained for use by internal Shiro components as necessary. 57 */ 58 class Builder extends Subject.Builder { 59 60 /** 61 * Constructs a new {@code Web.Builder} instance using the {@link SecurityManager SecurityManager} obtained by 62 * calling {@code SecurityUtils.}{@link SecurityUtils#getSecurityManager() getSecurityManager()}. If you want 63 * to specify your own SecurityManager instance, use the 64 * {@link #Builder(SecurityManager, ServletRequest, ServletResponse)} constructor instead. 65 * 66 * @param request the incoming ServletRequest that will be associated with the built {@code WebSubject} instance. 67 * @param response the outgoing ServletRequest paired with the ServletRequest that will be associated with the 68 * built {@code WebSubject} instance. 69 */ 70 public Builder(ServletRequest request, ServletResponse response) { 71 this(SecurityUtils.getSecurityManager(), request, response); 72 } 73 74 /** 75 * Constructs a new {@code Web.Builder} instance using the specified {@code SecurityManager} instance to 76 * create the {@link WebSubject WebSubject} instance. 77 * 78 * @param securityManager the {@code SecurityManager SecurityManager} instance to use to build the 79 * {@code WebSubject} instance. 80 * @param request the incoming ServletRequest that will be associated with the built {@code WebSubject} 81 * instance. 82 * @param response the outgoing ServletRequest paired with the ServletRequest that will be associated 83 * with the built {@code WebSubject} instance. 84 */ 85 public Builder(SecurityManager securityManager, ServletRequest request, ServletResponse response) { 86 super(securityManager); 87 if (request == null) { 88 throw new IllegalArgumentException("ServletRequest argument cannot be null."); 89 } 90 if (response == null) { 91 throw new IllegalArgumentException("ServletResponse argument cannot be null."); 92 } 93 setRequest(request); 94 setResponse(response); 95 } 96 97 /** 98 * Overrides the parent implementation to return a new instance of a 99 * {@link DefaultWebSubjectContext DefaultWebSubjectContext} to account for the additional request/response 100 * pair. 101 * 102 * @return a new instance of a {@link DefaultWebSubjectContext DefaultWebSubjectContext} to account for the 103 * additional request/response pair. 104 */ 105 @Override 106 protected SubjectContext newSubjectContextInstance() { 107 return new DefaultWebSubjectContext(); 108 } 109 110 /** 111 * Called by the {@code WebSubject.Builder} constructor, this method places the request object in the 112 * context map for later retrieval. 113 * 114 * @param request the incoming ServletRequest that triggered the creation of the {@code WebSubject} instance. 115 * @return 'this' for method chaining. 116 */ 117 protected Builder setRequest(ServletRequest request) { 118 if (request != null) { 119 ((WebSubjectContext) getSubjectContext()).setServletRequest(request); 120 } 121 return this; 122 } 123 124 /** 125 * Called by the {@code WebSubject.Builder} constructor, this method places the response object in the 126 * context map for later retrieval. 127 * 128 * @param response the outgoing ServletRequest paired with the ServletRequest that triggered the creation of 129 * the {@code WebSubject} instance. 130 * @return 'this' for method chaining. 131 */ 132 protected Builder setResponse(ServletResponse response) { 133 if (response != null) { 134 ((WebSubjectContext) getSubjectContext()).setServletResponse(response); 135 } 136 return this; 137 } 138 139 /** 140 * Returns {@link #buildSubject() super.buildSubject()}, but additionally ensures that the returned instance 141 * is an {@code instanceof} {@link WebSubject WebSubject} and to support a type-safe method so a caller 142 * does not have to cast. Per the parent class's method JavaDoc, this method will return a new instance 143 * each time it is called. 144 * 145 * @return a new {@link WebSubject WebSubject} instance built by this {@code Builder}. 146 */ 147 public WebSubject buildWebSubject() { 148 Subject subject = super.buildSubject(); 149 if (!(subject instanceof WebSubject)) { 150 String msg = "Subject implementation returned from the SecurityManager was not a " 151 + WebSubject.class.getName() + " implementation. Please ensure a Web-enabled SecurityManager " 152 + "has been configured and made available to this builder."; 153 throw new IllegalStateException(msg); 154 } 155 return (WebSubject) subject; 156 } 157 } 158 159 }