Instead of getProvider() you might need to use getRsServiceProvider() depending on your version.
You can also use GLOBALS.getInstance() (or getRsService() in older versions) to directly retrieve an instance instead of a provider.
The ServletRequest then allows you to access the URL parameters, for example, via
Finally, if you are planning to execute the script via the scriptAccess Servlet, then you can access the request directly via the then predefined variable
httpRequest. Thus, the above could be shortened to
So far I have this… The HttpServletRequest appears to be null (according to the output of the logger). I’m not quite sure how (or if it’s even possible) to pass GLOBALS to the ShiroPAM class.
package pam
import net.datenwerke.rs.authenticator.client.login.dto.UserPasswordAuthToken
import net.datenwerke.rs.authenticator.client.login.pam.UserPasswordClientPAM
import net.datenwerke.security.client.login.AuthToken
import net.datenwerke.security.service.authenticator.AuthenticationResult
import net.datenwerke.security.service.authenticator.ReportServerPAM
import net.datenwerke.security.service.authenticator.hooks.PAMHook
import net.datenwerke.security.service.usermanager.UserManagerService
import net.datenwerke.security.service.usermanager.entities.User
import javax.servlet.http.HttpServletRequest
import net.datenwerke.rs.scripting.service.scripting.scriptservices.GlobalsWrapper
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.logging.Logger;
Logger logger = Logger.getLogger("ShiroPAM");
logger.severe("@@@@ ShiroPAM INIT @@@@");
requestProvider = GLOBALS.getProvider(HttpServletRequest.class);
HttpServletRequest req = requestProvider.get();
final ShiroPAM shiroPAM = GLOBALS.injector.getInstance(ShiroPAM.class);
GLOBALS.services.callbackRegistry.attachHook("SHIRO_PAM", PAMHook.class, new PAMHook(){
public void beforeStaticPamConfig(LinkedHashSet<ReportServerPAM> pams){
pams.add(shiroPAM);
}
public void afterStaticPamConfig(LinkedHashSet<ReportServerPAM> pams){
}
});
public class ShiroPAM implements ReportServerPAM {
private final UserManagerService userManagerService;
private final Provider<HttpServletRequest> requestProvider;
private final GlobalsWrapper GLOBALS;
Logger logger = Logger.getLogger("ShiroPAM");
@Inject
public ShiroPAM(Provider<HttpServletRequest> requestProvider,
UserManagerService userManagerService) {
this.userManagerService = userManagerService;
this.requestProvider = requestProvider;
}
@Override
public AuthenticationResult authenticate(AuthToken[] tokens) {
// So if you have an SSO solution, this authenticate method will be your point of extension.
//def requestProvider = GLOBALS.getProvider(HttpServletRequest.class);
HttpServletRequest req = requestProvider.get();
String username = "";
String paramname = "uid";
logger.severe("Query string:" + req.getQueryString());
logger.severe("Parameter: " + req.getParts());
username = req.getParameter(paramname);
//username = "root";
return new AuthenticationResult(true, userManagerService.getUserByName(username),true);
}
@Override
public String getClientModuleName() {
return null;
}
}
I’m trying to read abelincoln from the url querystring. Should I be taking a different approach? Will this HTML page even pass the entire querystring to reportserver?
See below:
package net.datenwerke.rs.authenticator.service.pam.custom;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import net.datenwerke.rs.utils.misc.IPUtils;
import net.datenwerke.rs.utils.properties.ApplicationPropertiesService;
import net.datenwerke.security.client.login.AuthToken;
import net.datenwerke.security.service.authenticator.AuthenticationResult;
import net.datenwerke.security.service.authenticator.ReportServerPAM;
import net.datenwerke.security.service.usermanager.UserManagerService;
import net.datenwerke.rs.utils.crypto.PasswordHasher;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
*
* @author Tom
*/
public class CustomAuthenticatorPAM implements ReportServerPAM{
private final Logger logger = Logger.getLogger(getClass().getName());
private final static String IP_ADDRESSES_PROPERTY_NAME = "rs.authenticator.iprestriction.addresses";
private final Provider<HttpServletRequest> requestProvider;
private final ApplicationPropertiesService propertiesService;
private final IPUtils iputils;
private final UserManagerService userManagerService;
private final PasswordHasher passwordHasher;
@Inject
public CustomAuthenticatorPAM(
Provider<HttpServletRequest> requestProvider,
UserManagerService userManagerService,
ApplicationPropertiesService propertiesService,
PasswordHasher passwordHasher,
IPUtils iputils) {
this.requestProvider = requestProvider;
this.propertiesService = propertiesService;
this.iputils = iputils;
this.userManagerService = userManagerService;
this.passwordHasher = passwordHasher;
}
public AuthenticationResult authenticate(AuthToken[] tokens) {
/* load ip addresses */
String ipAddresses = propertiesService.getString(IP_ADDRESSES_PROPERTY_NAME);
/* get request */
HttpServletRequest request = requestProvider.get();
String remoteAddress = request.getRemoteAddr();
String uid = request.getParameter("uid");
/*
for(String ipString : ipAddresses.split(":")){
ipString = ipString.trim();
if(iputils.contains(ipString, remoteAddress))
return new AuthenticationResult(true, null);
}
*/
logger.info("UserID: " + uid);
logger.info("Remote Address: " + remoteAddress);
//logger.info("Blocked access from: " + remoteAddress);
return new AuthenticationResult(true, userManagerService.getUserByName(uid),true);
//return new AuthenticationResult(true, null);
}
public String getClientModuleName() {
return null;
}
}
the url parameters used with the ReportServer.html page are not available in authenticator modules, but the authentication scheme you describe should work without it:
In addition to the script you use to generate your uids create a second script, that validates the uids, logs in the user and issues a redirect to the host page.