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