Skip to content

Instantly share code, notes, and snippets.

@rplantiko
Created August 15, 2016 07:53

Revisions

  1. rplantiko created this gist Aug 15, 2016.
    231 changes: 231 additions & 0 deletions RedirectLogin.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,231 @@
    package loginServices;

    import com.sap.security.core.logon.imp.SAPJ2EECallbackHandler;
    import com.sap.engine.interfaces.security.auth.LoginContextFactory;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.security.auth.login.LoginContext;
    import javax.security.auth.login.LoginException;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.RequestDispatcher;
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.List;
    import javax.servlet.http.Cookie;

    import java.net.URL;
    import java.net.MalformedURLException;
    import java.net.HttpURLConnection;
    import java.net.HttpCookie;

    public class RedirectLogin extends HttpServlet
    {

    private String authenticationStack;
    private String authenticationRealm;

    public void init()
    {
    ServletContext servletContext = getServletContext();
    this.authenticationStack = servletContext.getInitParameter("authenticationStack");
    this.authenticationRealm = servletContext.getInitParameter("authenticationRealm");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
    doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {

    // Sehr gern hätte ich es auf diese Weise gemacht - aber das ging nicht:
    // RequestDispatcher rd = request.getRequestDispatcher("/nwa");
    // rd.include(request,response);

    try {

    PrintWriter w = response.getWriter();

    HttpServletRequest httpRequest = (HttpServletRequest) request;

    Cookie mysapsso2;
    mysapsso2 = getMYSAPSSO2( httpRequest );
    if (mysapsso2==null) {
    mysapsso2 = createMYSAPSSO2( httpRequest );
    }

    if (mysapsso2 != null) {
    String redirectURL = getRedirectURL(request);
    response.addCookie( mysapsso2 );
    response.sendRedirect(redirectURL);
    response.getWriter().println("OK");
    }
    else throw new LoginException("Could not retrieve MYSAPSSO2 ticket");

    } catch (Throwable t) {

    response.setContentType("text/plain");
    response.setStatus(401);

    PrintWriter w = response.getWriter();
    w.println("Exception: " + t.getMessage() );
    t.printStackTrace(w);

    }

    }



    protected void doPost1(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
    try
    {

    if (doLogin(request)) {
    SAPJ2EECallbackHandler callbackHandler = new SAPJ2EECallbackHandler(request, response);
    LoginContext lc = LoginContextFactory.getLoginContext("ticket", callbackHandler);
    lc.login();
    }

    String redirectURL = getRedirectURL(request);
    response.sendRedirect(redirectURL);
    response.getWriter().println("OK");

    }
    catch (LoginException le) {

    if (this.authenticationRealm.matches("\\S")) {
    response.setHeader("WWW-Authenticate", this.authenticationRealm);
    }

    response.setContentType("text/html");
    response.setStatus(401);

    PrintWriter w = response.getWriter();
    w.println("<html><body><h2>Not authorized (RedirectLogin.java)</h2>");
    if (traceMode(request)) {
    w.println("Authentication stack: "+this.authenticationStack);
    w.println("Authentication realm: "+this.authenticationRealm);
    w.println("Exception cause: "+le.getMessage());
    w.println("<pre>");
    le.printStackTrace(w);
    w.println("</pre>");
    Throwable t = le.getCause();
    if (t!=null) {
    w.println("Cause: "+t.getMessage()+"<pre>");
    t.printStackTrace();
    w.println("</pre>");
    }
    else {
    w.println("(no causing exception given)");
    }
    }
    w.println("</body></html>");
    }
    }

    private Cookie getMYSAPSSO2(HttpServletRequest httpRequest) {
    Cookie[] cookies = httpRequest.getCookies();
    if (cookies != null && cookies.length > 0) {
    for (Cookie c : cookies) {
    if (c.getName().equals("MYSAPSSO2")) {
    return c;
    }
    }
    }
    return null;
    }

    private Cookie createMYSAPSSO2( HttpServletRequest request ) throws LoginException, IOException, MalformedURLException {

    // Authentifizierung verlangt die Existenz des Headerfelds
    if ( request.getHeader("dxmSAPusername") == null ) {
    throw new LoginException("No Airlock authentication");
    }

    // HTTP-Verbindung zu /nwa aufmachen, um MYSAPSSO2 Cookie zu erzeugen
    URL nwa = new URL( request.getRequestURL().toString().replace("/RedirectLogin/redirect","/nwa") );
    HttpURLConnection c = (HttpURLConnection)nwa.openConnection();
    // Alle Headerfelder ausser cookie wie ein Proxy übernehmen
    Enumeration<String> headerNames = request.getHeaderNames();
    if (headerNames != null) {
    while (headerNames.hasMoreElements()) {
    String headerFieldName = headerNames.nextElement();
    if (headerFieldName.equals("cookie")) continue;
    c.setRequestProperty(headerFieldName,request.getHeader(headerFieldName) );
    }
    }

    // (synchronen) Request auf /nwa ausführen...
    c.connect();

    // Hat geklappt
    if (c.getResponseCode( ) == 200) {
    // MYSAPSSO2 Cookie aus der Antwort herausschälen
    Map<String, List<String>> responseHeaderFields = c.getHeaderFields();
    List<String> cookiesHeader = responseHeaderFields.get("set-cookie");
    if (cookiesHeader != null) {
    for (String cs : cookiesHeader) {
    HttpCookie ch = HttpCookie.parse( cs ).get(0);
    if (ch.getName().equals("MYSAPSSO2")) {
    return servletCookie(ch);
    }
    }
    throw new LoginException("Authentication response contains not MYSAPSSO2 ticket");
    } else throw new LoginException("Authentication response incomplete"+responseHeaderFields);
    } else throw new LoginException("HTTP error code " + c.getResponseCode() + " from authentication");

    }

    private Cookie servletCookie(HttpCookie c){
    Cookie _c=new Cookie(c.getName(),c.getValue());
    if (c.getComment() != null) {
    _c.setComment(c.getComment());
    }
    if (c.getDomain() != null) {
    _c.setDomain(c.getDomain());
    }
    if (c.getPath() != null) {
    _c.setPath(c.getPath());
    }
    _c.setSecure(c.getSecure());
    _c.setVersion(c.getVersion());
    //_c.setHttpOnly(c.getDiscard());
    _c.setMaxAge((int)c.getMaxAge());
    return _c;
    }

    private String getRedirectURL(HttpServletRequest request)
    {
    String dest = request.getHeader("migros-redirect");
    if ((dest == null) || (dest.equals("")))
    {
    dest = request.getParameter("migros-redirect");
    if ((dest == null) || (dest.equals("")))
    {
    dest = getServletContext().getInitParameter("defaultRedirectURL");
    }
    }
    return dest;
    }

    private boolean traceMode(HttpServletRequest request) {
    String trc = request.getParameter("trc");
    return ((trc != null) && trc.equals("on"));
    }

    private boolean doLogin(HttpServletRequest request) {
    String login = request.getParameter("login");
    return ((login == null) || !login.equals("off"));
    }

    }