Skip to content

Instantly share code, notes, and snippets.

@rplantiko
Created August 15, 2016 07:53
Show Gist options
  • Save rplantiko/d726ff3f810331bfdb30f7e3acbc535d to your computer and use it in GitHub Desktop.
Save rplantiko/d726ff3f810331bfdb30f7e3acbc535d to your computer and use it in GitHub Desktop.
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"));
}
}
@rplantiko
Copy link
Author

Workaround by internally calling the /nwa address, for calling the authentication stack and retrieving the MYSAPSSO2 cookie.
This workaround was necessary since the normal login didn't work after upgrade from Java NW 7.0 to 7.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment