One of the simple servlets that you might have seen is a servlet that accepts basic auth header (WWW-Authenticate) and gives the user a security session. This is a simple implementation of one such servlet. It checks if the request already has a basic auth header. If not it asks client to send one. If basic auth header is present that is used to authenticate the user and return the user a single sign on token in the form of a cookie or a String. This servlet can be tested from browser either by entering credentials manually in the basic auth credential prompt. It can also be called from soapui.Soapui can create the basic auth header if user supplied the username and password. This uses one of classes named AuditRecord I wrote in my previous posts (link here)
import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.codec.binary.Base64; public class BasicAuthLoginServlet extends HttpServlet { private static final long serialVersionUID = -6527953079135467056L; private static final String SSO_COOKIE_NAME = "yourcompany-sso"; private static final String SSO_COOKIE_DOMAIN = ".yourcompany.com"; private static final String BASIC_AUTH_HEADER_NAME = "WWW-Authenticate"; private static final String BASIC_AUTH_HEADER_VALUE = "BASIC realm=\"basic_realm\""; private static final String SERVLET_NAME = "BasicAuthLoginServlet"; private final static Pattern basicCredentialPattern = Pattern .compile("([^:]+):(.+)"); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { final AuditRecord auditRecord = new AuditRecord(request, SERVLET_NAME); final String auth = request.getHeader("Authorization"); try { // if user hasn't sent the basic auth info, ask him if (auth == null) { auditRecord.append("auth header is null"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.addHeader(BASIC_AUTH_HEADER_NAME, BASIC_AUTH_HEADER_VALUE); return; } // authenticate user String ssoToken = loginWithBasic(auth, auditRecord); // if ssoToken === null that means authentication failed - send 401 if (ssoToken == null) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } // if it has come here that means user has authenticated // successfully auditRecord.append("authentication successful"); // if it has come here that means authentication and authorization // is successful - send 200 auditRecord.append("success"); setSingleSignonCookie(response, "token"); sendSuccess(response); } finally { auditRecord.log(); } } private void sendSuccess(HttpServletResponse response) throws IOException { response.setStatus(HttpServletResponse.SC_OK); response.setContentType("text/plain"); response.getWriter().write("Login successful"); } private void setSingleSignonCookie(HttpServletResponse response, String ssoToken) { final Cookie cookie = new Cookie(SSO_COOKIE_NAME, ssoToken); cookie.setDomain(SSO_COOKIE_DOMAIN); cookie.setPath("/"); cookie.setSecure(true); response.addCookie(cookie); } /** * * @param authHeader * @param auditRecord * @return if authenticated returns a token that represents user's * singlesignontoken */ private String loginWithBasic(String authHeader, AuditRecord auditRecord) { String username = null; String password = null; String result = null; if (authHeader != null && authHeader.toUpperCase().startsWith("BASIC ")) { String input = new String(Base64.decodeBase64(authHeader.substring( 6).getBytes())); Matcher m = basicCredentialPattern.matcher(input); if (m.find()) { username = m.group(1); password = m.group(2); } } if (username != null && password != null) { auditRecord.append("username", username); // call some db or ldap and authenticate using your own logic and // give user a single sing on token if (username.equals("test") && password.equals("test")) { result = "dummySSOToken"; } } return result; } }
No comments:
Post a Comment