1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.security.jaspi;
15
16 import java.security.Principal;
17 import java.util.Map;
18 import java.util.Set;
19
20 import javax.security.auth.Subject;
21 import javax.security.auth.message.AuthException;
22 import javax.security.auth.message.AuthStatus;
23 import javax.security.auth.message.callback.CallerPrincipalCallback;
24 import javax.security.auth.message.callback.GroupPrincipalCallback;
25 import javax.security.auth.message.config.ServerAuthConfig;
26 import javax.security.auth.message.config.ServerAuthContext;
27 import javax.servlet.ServletRequest;
28 import javax.servlet.ServletResponse;
29
30 import org.eclipse.jetty.security.Authenticator;
31 import org.eclipse.jetty.security.IdentityService;
32 import org.eclipse.jetty.security.ServerAuthException;
33 import org.eclipse.jetty.security.UserAuthentication;
34 import org.eclipse.jetty.security.authentication.DeferredAuthentication;
35 import org.eclipse.jetty.server.Authentication;
36 import org.eclipse.jetty.server.UserIdentity;
37 import org.eclipse.jetty.server.Authentication.User;
38
39
40
41
42 public class JaspiAuthenticator implements Authenticator
43 {
44 private final ServerAuthConfig _authConfig;
45
46 private final Map _authProperties;
47
48 private final ServletCallbackHandler _callbackHandler;
49
50 private final Subject _serviceSubject;
51
52 private final boolean _allowLazyAuthentication;
53
54 private final IdentityService _identityService;
55
56 private final DeferredAuthentication _deferred;
57
58 public JaspiAuthenticator(ServerAuthConfig authConfig, Map authProperties, ServletCallbackHandler callbackHandler, Subject serviceSubject,
59 boolean allowLazyAuthentication, IdentityService identityService)
60 {
61
62 if (callbackHandler == null) throw new NullPointerException("No CallbackHandler");
63 if (authConfig == null) throw new NullPointerException("No AuthConfig");
64 this._authConfig = authConfig;
65 this._authProperties = authProperties;
66 this._callbackHandler = callbackHandler;
67 this._serviceSubject = serviceSubject;
68 this._allowLazyAuthentication = allowLazyAuthentication;
69 this._identityService = identityService;
70 this._deferred = new DeferredAuthentication(this);
71 }
72
73 public void setConfiguration(AuthConfiguration configuration)
74 {
75 }
76
77 public String getAuthMethod()
78 {
79 return "JASPI";
80 }
81
82 public Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException
83 {
84 JaspiMessageInfo info = new JaspiMessageInfo(request, response, mandatory);
85 request.setAttribute("org.eclipse.jetty.security.jaspi.info", info);
86
87 Authentication a = validateRequest(info);
88
89
90 if (_allowLazyAuthentication && !info.isAuthMandatory() && a == Authentication.UNAUTHENTICATED)
91 a =_deferred;
92 return a;
93 }
94
95
96 public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
97 {
98 JaspiMessageInfo info = (JaspiMessageInfo) req.getAttribute("org.eclipse.jetty.security.jaspi.info");
99 if (info == null) throw new NullPointerException("MessageInfo from request missing: " + req);
100 return secureResponse(info, validatedUser);
101 }
102
103
104 public Authentication validateRequest(JaspiMessageInfo messageInfo) throws ServerAuthException
105 {
106 try
107 {
108 String authContextId = _authConfig.getAuthContextID(messageInfo);
109 ServerAuthContext authContext = _authConfig.getAuthContext(authContextId, _serviceSubject, _authProperties);
110 Subject clientSubject = new Subject();
111
112 AuthStatus authStatus = authContext.validateRequest(messageInfo, clientSubject, _serviceSubject);
113
114 if (authStatus == AuthStatus.SEND_CONTINUE) return Authentication.SEND_CONTINUE;
115 if (authStatus == AuthStatus.SEND_FAILURE) return Authentication.SEND_FAILURE;
116
117 if (authStatus == AuthStatus.SUCCESS)
118 {
119 Set<UserIdentity> ids = clientSubject.getPrivateCredentials(UserIdentity.class);
120 UserIdentity userIdentity;
121 if (ids.size() > 0)
122 {
123 userIdentity = ids.iterator().next();
124 }
125 else
126 {
127 CallerPrincipalCallback principalCallback = _callbackHandler.getThreadCallerPrincipalCallback();
128 if (principalCallback == null) { return Authentication.UNAUTHENTICATED; }
129 Principal principal = principalCallback.getPrincipal();
130 if (principal == null)
131 {
132 String principalName = principalCallback.getName();
133 Set<Principal> principals = principalCallback.getSubject().getPrincipals();
134 for (Principal p : principals)
135 {
136 if (p.getName().equals(principalName))
137 {
138 principal = p;
139 break;
140 }
141 }
142 if (principal == null) { return Authentication.UNAUTHENTICATED; }
143 }
144 GroupPrincipalCallback groupPrincipalCallback = _callbackHandler.getThreadGroupPrincipalCallback();
145 String[] groups = groupPrincipalCallback == null ? null : groupPrincipalCallback.getGroups();
146 userIdentity = _identityService.newUserIdentity(clientSubject, principal, groups);
147 }
148 return new UserAuthentication(getAuthMethod(), userIdentity);
149 }
150 if (authStatus == AuthStatus.SEND_SUCCESS)
151 {
152
153 return Authentication.SEND_SUCCESS;
154 }
155
156 throw new NullPointerException("No AuthStatus returned");
157 }
158 catch (AuthException e)
159 {
160 throw new ServerAuthException(e);
161 }
162 }
163
164 public boolean secureResponse(JaspiMessageInfo messageInfo, Authentication validatedUser) throws ServerAuthException
165 {
166 try
167 {
168 String authContextId = _authConfig.getAuthContextID(messageInfo);
169 ServerAuthContext authContext = _authConfig.getAuthContext(authContextId, _serviceSubject, _authProperties);
170
171
172 AuthStatus status = authContext.secureResponse(messageInfo, _serviceSubject);
173 return (AuthStatus.SEND_SUCCESS.equals(status));
174 }
175 catch (AuthException e)
176 {
177 throw new ServerAuthException(e);
178 }
179 }
180
181 }