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