on 03-21-2011 10:58 AM
Hi there,
we have an own authentication stack named "ticket" and want to trigger its checks programmatically in a servlet, serving as a kind of gatekeeper and redirecting to the proper URL if login was sucessful. According to the documentation, this is one of two options ("programmatically" vs. "configured").
Since I didn't find an appropriate code sample, I tried to figure it out on my own:
protected void doPost(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
try {
LoginContext lc = new LoginContext(authenticationStack);
lc.login();
String redirectURL = getRedirectURL(request);
response.sendRedirect(redirectURL);
}
catch (LoginException le) {
...
}
}
When the servlet is called, we get the error:
Error: No CallbackHandler available to garner authentication information from the user. ticket
I guess that the CallbackHandler has to somehow pass the HTTP request object to the authentication layer. I have seen that there is a constructor for LoginContext having a callbackHandler as second argument. But I wonder what to fill in there.
Can someone help me what to fill in for "callbackHandler"? Is there a sample code containing an implementation of this interface for this very simple and straightforward servlet case?
Thanks and regards,
Rüdiger
I don't close the message yet. But it seems I found the essential part of the answer. SAP's standard callback handler can be accessed by
new com.sap.security.core.logon.imp.SAPJ2EECallbackHandler(request,response)
I can fill this into my login context constructor:
try {
SAPJ2EECallbackHandler sch = new SAPJ2EECallbackHandler(request, response);
LoginContext lc = new LoginContext(authenticationStack, sch);
lc.login();
String redirectURL = getRedirectURL(request);
response.sendRedirect(redirectURL);
} catch (LoginException le) {
// Fallback for Basic Authentication,
// if first attempt to login didn't work (BASIC is part of our stack)
response.setHeader( "WWW-Authenticate", authenticationRealm);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
I will do some tests. I will not close this message before having found that this really solves the problem.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The tests were positive. The above code will go productive.
Just for documentation purposes, before finally deleting unused code parts, I copy them into this thread:
Invoking a single authentication method, not a complete stack
This can be achieved with code similar to the following:
/* Einzelne Anmeldung, kein ganzer Stack!!! */
ILogonAuthentication authenticator = UMFactory.getLogonAuthenticator();;
try {
authenticator.logon(request, response, authenticationStack);
String redirectURL = getRedirectURL(request);
response.sendRedirect(redirectURL);
} catch (LoginException e) {
response.setHeader( "WWW-Authenticate", authenticationRealm);
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"SRM-Anmeldung '" + authenticationStack + "' fehlgeschlagen");
}
A callback handler for test purposes
If you want to know which callbacks are triggered by your authentication stack, you can define your own callback handler and pass it to the login context instead.
I worked with a local (inner) class for this purpose. I had to use reflection to dynamically call a "getName" method, since the actual callback classes where partly hidden.
/* Wird nicht mehr benötigt, wir können direkt den SAPJ2EECallbackHandler instanziieren */
private static class TheCallbackHandler implements CallbackHandler {
private HttpServletRequest request;
private HttpServletResponse response;
private TheCallbackHandler(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
NameCallback nc = null;
PrintWriter rw = response.getWriter();
rw.println(callbacks.length + "Zeilen. <br>");
for (int i=0;i<callbacks.length;i++) {
rw.println( i + ":" + callbacks<i>.getClass().getName()+"<br>");
}
for (int i = 0; i < callbacks.length; i++) {
// Müssen Reflection benutzen, denn die folgende Klasse ist leider unerreichbar
// com.sap.engine.lib.security.http.HttpGetterCallback
String getName = null;
Object retVal;
try {
retVal = callbacks<i>.getClass().getMethod("getName",null).invoke(callbacks<i>, null );
getName = (String) retVal ;
rw.println( getName + "<br>");
} catch ( Throwable e) {
e.printStackTrace( response.getWriter() );
}
}
}
User | Count |
---|---|
91 | |
10 | |
10 | |
9 | |
9 | |
7 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.