...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
package org.my;
import java.io.IOException;
import java.security.Principal;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.MessagePolicy;
import javax.security.auth.message.callback.CallerPrincipalCallback;
import javax.security.auth.message.callback.GroupPrincipalCallback;
import javax.security.auth.message.module.ServerAuthModule;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SpAsBridgeSam implements ServerAuthModule {
public static class MyOrgPrincipal implements Principal {
public MyOrgPrincipal(String name) {
this.name = name;
}
private final String name;
@Override
public String getName() {
return name;
}
}
private static final Class<?>[] SUPPORTED_MESSAGE_TYPES = new Class<?>[] { HttpServletRequest.class, HttpServletResponse.class };
private static final String LOGIN_URL = "http://my.org/Shibboleth.sso/Login";
private static final String LOGOUT_URL = "http://my.org/Shibboleth.sso/Logout";
private boolean isProtectedResource;
private CallbackHandler ch;
// Post-construct initialization goes here
@Override
public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler ch, Map options) throws AuthException {
this.ch = ch;
isProtectedResource = requestPolicy.isMandatory();
}
// Authentication logic and optional request pre-processing goes here
@Override
public AuthStatus validateRequest(MessageInfo mi, Subject client, Subject service) throws AuthException {
HttpServletRequest hreq = (HttpServletRequest) mi.getRequestMessage();
HttpServletResponse hres = (HttpServletResponse) mi.getResponseMessage();
String username = getUsername(hreq);
String[] groups = getUsergroups(hreq);
if ((username != null) && (!username.trim().isEmpty()) && (groups != null)) {
try {
ch.handle(new Callback[] {
new CallerPrincipalCallback(client, new MyOrgPrincipal(username)),
new GroupPrincipalCallback(client, groups) });
}
catch (UnsupportedCallbackException | IOException e) {
e.printStackTrace();
throw new AuthException("Could not authenticate user.");
}
return AuthStatus.SUCCESS;
}
else if (!isProtectedResource) {
return AuthStatus.SUCCESS;
}
else {
try {
hres.sendRedirect(LOGIN_URL);
}
catch (IOException ioe) {
ioe.printStackTrace();
throw new AuthException("Could not authenticate user.");
}
return AuthStatus.SEND_CONTINUE;
}
}
// Validation of response and optional post-processing goes here
// Not typically used, as --unless it had initially been wrapped-- the response is already committed
// by the time this method is called
@Override
public AuthStatus secureResponse(MessageInfo messageInfo, Subject service) throws AuthException {
return AuthStatus.SEND_SUCCESS;
}
// Logout logic goes here
// The spec is a bit unclear regarding this method, thus I'm unsure whether it's best to directly modify the Subject
// or use container facilities
@Override
public void cleanSubject(MessageInfo mi, Subject client) throws AuthException {
HttpServletRequest hreq = (HttpServletRequest) mi.getRequestMessage();
HttpServletResponse hres = (HttpServletResponse) mi.getResponseMessage();
HttpSession hs = hreq.getSession(false);
if (hs != null) {
try {
hs.invalidate();
}
catch (IllegalStateException ise) {
ise.printStackTrace();
throw new AuthException("Could not invalidate user session.");
}
}
try {
hreq.logout();
hres.sendRedirect(LOGOUT_URL);
}
catch (ServletException | IOException e) {
e.printStackTrace();
throw new AuthException("Could not complete user logout.");
}
}
@Override
public Class<?>[] getSupportedMessageTypes() {
return SUPPORTED_MESSAGE_TYPES;
}
private String getUsername(HttpServletRequest hreq) {
return (String) hreq.getAttribute("eduPersonPrincipalName");
}
private String[] getUsergroups(HttpServletRequest hreq) {
String groupsAttribute = (String) hreq.getAttribute("eduPersonAffiliation");
String[] groups = null;
if (groupsAttribute != null) {
groups = groupsAttribute.split(";");
for (int i = 0; i < groups.length; i++) {
groups[i] = groups[i].trim();
}
}
return groups;
}
} |
...