1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.shiro.spring.remoting;
20
21 import org.apache.shiro.SecurityUtils;
22 import org.apache.shiro.mgt.SecurityManager;
23 import org.apache.shiro.subject.ExecutionException;
24 import org.apache.shiro.subject.Subject;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import org.springframework.remoting.support.DefaultRemoteInvocationExecutor;
28 import org.springframework.remoting.support.RemoteInvocation;
29
30 import java.io.Serializable;
31 import java.lang.reflect.InvocationTargetException;
32 import java.util.concurrent.Callable;
33
34
35
36
37
38
39
40
41
42
43 public class SecureRemoteInvocationExecutor extends DefaultRemoteInvocationExecutor {
44
45
46
47
48
49
50
51
52
53
54 private static final Logger LOGGER = LoggerFactory.getLogger(SecureRemoteInvocationExecutor.class);
55
56
57
58
59
60 private SecurityManager securityManager;
61
62
63
64
65
66
67
68
69
70 public void setSecurityManager(org.apache.shiro.mgt.SecurityManager securityManager) {
71 this.securityManager = securityManager;
72 }
73
74
75
76
77 @SuppressWarnings({"unchecked"})
78 public Object invoke(final RemoteInvocation invocation, final Object targetObject)
79 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
80
81 try {
82 SecurityManager securityManager =
83 this.securityManager != null ? this.securityManager : SecurityUtils.getSecurityManager();
84
85 Subject.Builder builder = new Subject.Builder(securityManager);
86
87 String host = (String) invocation.getAttribute(SecureRemoteInvocationFactory.HOST_KEY);
88 if (host != null) {
89 builder.host(host);
90 }
91
92 Serializable sessionId = invocation.getAttribute(SecureRemoteInvocationFactory.SESSION_ID_KEY);
93 if (sessionId != null) {
94 builder.sessionId(sessionId);
95 } else {
96 if (LOGGER.isTraceEnabled()) {
97 LOGGER.trace("RemoteInvocation did not contain a Shiro Session id attribute under "
98 + "key [" + SecureRemoteInvocationFactory.SESSION_ID_KEY + "]. A Subject based "
99 + "on an existing Session will not be available during the method invocation.");
100 }
101 }
102
103 Subject subject = builder.buildSubject();
104 return subject.execute(new Callable() {
105 public Object call() throws Exception {
106 return SecureRemoteInvocationExecutor.super.invoke(invocation, targetObject);
107 }
108 });
109 } catch (ExecutionException e) {
110 Throwable cause = e.getCause();
111 if (cause instanceof NoSuchMethodException) {
112 throw (NoSuchMethodException) cause;
113 } else if (cause instanceof IllegalAccessException) {
114 throw (IllegalAccessException) cause;
115 } else if (cause instanceof InvocationTargetException) {
116 throw (InvocationTargetException) cause;
117 } else {
118 throw new InvocationTargetException(cause);
119 }
120 } catch (Throwable t) {
121 throw new InvocationTargetException(t);
122 }
123 }
124 }