Merge branch 'shibIntegration' into develop
This commit is contained in:
commit
ba89f7f02d
src/main
@ -1,5 +1,9 @@
|
||||
package se.su.dsv.scipro;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.wicket.Page;
|
||||
@ -9,6 +13,7 @@ import org.apache.wicket.Response;
|
||||
import org.apache.wicket.Session;
|
||||
import org.apache.wicket.authorization.strategies.CompoundAuthorizationStrategy;
|
||||
import org.apache.wicket.protocol.http.WebApplication;
|
||||
import org.apache.wicket.protocol.http.WebRequest;
|
||||
import org.odlabs.wiquery.ui.themes.IThemableApplication;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
@ -44,18 +49,6 @@ import se.su.dsv.scipro.knol.resource.page.ResourcePage;
|
||||
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
|
||||
import se.su.dsv.scipro.loginlogout.pages.LogoutPage;
|
||||
import se.su.dsv.scipro.message.pages.PrivateMessagesPage;
|
||||
import se.su.dsv.scipro.peer.pages.PeerRequestSubmissionPage;
|
||||
import se.su.dsv.scipro.peer.pages.PeerReviewTemplateCreationPage;
|
||||
import se.su.dsv.scipro.peer.pages.PeerReviewTemplatePage;
|
||||
import se.su.dsv.scipro.peer.pages.PeerReviewTemplatePreviewPage;
|
||||
import se.su.dsv.scipro.peer.pages.ProjectPeerPortalPage;
|
||||
import se.su.dsv.scipro.peer.pages.ProjectPeerReviewGuidePage;
|
||||
import se.su.dsv.scipro.peer.pages.ProjectPeerReviewPage;
|
||||
import se.su.dsv.scipro.peer.pages.ProjectPeerStatsPage;
|
||||
import se.su.dsv.scipro.peer.pages.SupervisorPeerPortalPage;
|
||||
import se.su.dsv.scipro.peer.pages.SupervisorPeerReviewGuidePage;
|
||||
import se.su.dsv.scipro.peer.pages.SupervisorPeerReviewPage;
|
||||
import se.su.dsv.scipro.peer.pages.SupervisorPeerStatsPage;
|
||||
import se.su.dsv.scipro.project.pages.FinalSeminarProjectListPage;
|
||||
import se.su.dsv.scipro.project.pages.NoActiveProjectPage;
|
||||
import se.su.dsv.scipro.project.pages.ProjectEventPage;
|
||||
@ -69,6 +62,7 @@ import se.su.dsv.scipro.repository.pages.RepositoryDownloadPage;
|
||||
import se.su.dsv.scipro.repository.pages.SysAdminFilePage;
|
||||
import se.su.dsv.scipro.schedule.templates.pages.ScheduleTemplateDetailsPage;
|
||||
import se.su.dsv.scipro.security.auth.ComponentSecurityLogger;
|
||||
import se.su.dsv.scipro.security.auth.ExternalAuthenticationRequestHelper;
|
||||
import se.su.dsv.scipro.security.auth.MetaDataActionStrategy;
|
||||
import se.su.dsv.scipro.security.auth.RoleBasedAuthorizationStrategy;
|
||||
import se.su.dsv.scipro.supervisor.pages.SupervisorAntiPlagiarismLinkPage;
|
||||
@ -108,6 +102,11 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
|
||||
*/
|
||||
private String systemNotice = null;
|
||||
|
||||
/**
|
||||
* Logger instance.
|
||||
* @TODO Inject
|
||||
*/
|
||||
private Logger logger = Logger.getLogger(this.getClass());
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@ -274,8 +273,7 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void setKerberosConfigs(){
|
||||
javax.servlet.ServletContext context = getServletContext();
|
||||
Logger logger = Logger.getRootLogger();
|
||||
java.util.Set<String> resources = context.getResourcePaths("/WEB-INF/classes/");
|
||||
Set<String> resources = context.getResourcePaths("/WEB-INF/classes/");
|
||||
if(!resources.contains(jaasPath) || !resources.contains(krb5Path)){
|
||||
logger.log(Level.FATAL, "Path to authentication config files not correct. " +
|
||||
"Users will not be able to log in!");
|
||||
@ -307,6 +305,49 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
|
||||
public Session newSession(Request request, Response response) {
|
||||
return new SciProSession(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebRequest newWebRequest(final HttpServletRequest request){
|
||||
final WebRequest webRequest = super.newWebRequest(request);
|
||||
if(attemptExternalAuthentication(webRequest)){
|
||||
logger.debug("External authentication used");
|
||||
}
|
||||
return webRequest;
|
||||
}
|
||||
/**
|
||||
* Private utility, just to keep stuff out of the calling method.
|
||||
* In short: scan incoming request for REMOTE_USER, check for a session, create one if none exists, attempt authentication and return status.
|
||||
* @param usingRequest
|
||||
* @return true if external auth was completed, false if not.
|
||||
*/
|
||||
private boolean attemptExternalAuthentication(final WebRequest usingRequest){
|
||||
SciProSession session = (SciProSession)getSessionStore().lookup(usingRequest);
|
||||
final ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(usingRequest.getHttpServletRequest());
|
||||
if(helper.isExternalAuthSupported()){//Attempt external auth
|
||||
if(session == null){//Can't do this without a usable session, attempt manual bind
|
||||
getSessionStore().bind(usingRequest,new SciProSession(usingRequest));
|
||||
session = (SciProSession)getSessionStore().lookup(usingRequest);
|
||||
}
|
||||
if(session != null){
|
||||
if(session.isLoggedIn()){
|
||||
if(!helper.isRemoteUserValid(session.getUser())){//This check may not be needed and may hinder performance, but better safe than sorry for now.
|
||||
logger.warn("User is logged in, but conflicting info is supplied via external authentication protocols.");
|
||||
}
|
||||
}else{
|
||||
//logger.info("Attempting sign in with external auth data");
|
||||
if(!helper.signIn(session)){
|
||||
logger.error("User passes external authentication but cannot be signed in.");
|
||||
}else{
|
||||
logger.debug("Signed in user '"+helper.getExternalAuthRemoteUser()+"' via external authentication");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
throw new IllegalStateException("External authentication was attempted, but no session was available.");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceReference getTheme(Session session) {
|
||||
|
@ -57,6 +57,9 @@ public class SciProSession extends WebSession {
|
||||
|
||||
private String loggedInIdentity = null;
|
||||
|
||||
//Logger instance
|
||||
private static Logger logger = Logger.getLogger(SciProSession.class);
|
||||
|
||||
/*
|
||||
* It's important not to hold the actual object, if we do, no changes to it
|
||||
* or it's attributes will be visible for the user unless they logout or re-select their active project.
|
||||
@ -105,16 +108,115 @@ public class SciProSession extends WebSession {
|
||||
return loggedInIdentity;
|
||||
}
|
||||
|
||||
|
||||
public synchronized boolean login(final String username, final String password) throws FailedLoginException, NullPointerException{
|
||||
final boolean loginSuccess = authenticate(username, password);
|
||||
if(loginSuccess){
|
||||
loggedIn = true;
|
||||
/**
|
||||
* Local login procedures, delegates authentication to authenticate() and sign in procedures to signInAuthenticatedUser() if authentication succeeds.
|
||||
* An administrator can log in as a different user in the system by using 'adminusername::otherusername' notation,
|
||||
* this is implemented as a regular login followed by a su-like switch (via switchAuthenticatedUser).
|
||||
* @param username is expected to be in the format "localdsvusername" or "localdsvusername::optionalotherusername".
|
||||
*/
|
||||
public boolean login(final String username, final String password) throws FailedLoginException, NullPointerException{
|
||||
String[] tmp = username.split("::");
|
||||
String authenticatedUserName = username;
|
||||
String switchToUserName = null;
|
||||
if(tmp.length > 0){
|
||||
authenticatedUserName = tmp[0];
|
||||
if(tmp.length > 1)
|
||||
switchToUserName = tmp[1];
|
||||
}
|
||||
return loginSuccess;
|
||||
//logger.info("Attempting authentication as "+authenticatedUserName);
|
||||
final boolean authenticationSuccess = authenticate(authenticatedUserName, password);
|
||||
if(!authenticationSuccess)
|
||||
return false;
|
||||
//logger.info("Successfully authenticated user "+authenticatedUserName);
|
||||
final boolean signInSuccess = signInAuthenticatedUser(authenticatedUserName,"DSV.SU.SE");
|
||||
if(switchToUserName != null){
|
||||
if(!switchAuthenticatedUser(switchToUserName,"DSV.SU.SE"))
|
||||
logger.error("Can't switch from '"+authenticatedUserName+"' to '"+switchToUserName+"'");
|
||||
}
|
||||
return signInSuccess;
|
||||
}
|
||||
/**
|
||||
* Sign in a user and bypass normal authentication routines completely.
|
||||
* This user has to already be present in database tables or login will fail.
|
||||
* @param username is expected to be one of the users registered username
|
||||
* @param realm is expected to be the matching realm from the supplied username
|
||||
* @return status of the sign-in request
|
||||
*/
|
||||
public boolean signInAuthenticatedUser(final String username, final String realm){
|
||||
//Query for the user
|
||||
user = userDao.getUserByUsername(username,realm);
|
||||
if(user == null){
|
||||
try{
|
||||
user = doUserLookup(username);
|
||||
if(user == null){
|
||||
throw new NullPointerException("No user with username "+username+" found in the database or in daisy.");
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
//Set mail-address session attributes
|
||||
setLoggedInIdentity(username+"@"+realm);
|
||||
if(user.getEmailAddress() == null || user.getEmailAddress().trim().equals("")){
|
||||
user.setEmailAddress(getLoggedInIdentity());
|
||||
user = userDao.save(user);
|
||||
}
|
||||
//Assign roles
|
||||
if(roleDao.isStudent(user)){
|
||||
iRoles.add(new Student());
|
||||
}
|
||||
if(roleDao.isExternal(user)){
|
||||
iRoles.add(new External());
|
||||
}
|
||||
if(roleDao.isEmployee(user)){
|
||||
iRoles.add(new Employee());
|
||||
}
|
||||
if(roleDao.isAdmin(user)){
|
||||
iRoles.add(new Admin());
|
||||
}
|
||||
if(roleDao.isSysadmin(user)){
|
||||
iRoles.add(new SysAdmin());
|
||||
}
|
||||
if(iRoles.isEmpty()){
|
||||
iRoles.add(new DefaultRole());
|
||||
}
|
||||
//Set active project from users settings
|
||||
UserSettings userSettings = userSettingsDao.getUserSettings(user);
|
||||
if(userSettings != null){
|
||||
Project activeProject = userSettings.getActiveProject();
|
||||
if(activeProject != null)
|
||||
activeProjectId = activeProject.getId();
|
||||
}
|
||||
else {
|
||||
userSettings = new UserSettings(user);
|
||||
}
|
||||
// With this userSettings.created() will return a users first login date and userSettings.modified() will return last login
|
||||
userSettings.setLastModified(new Date());
|
||||
userSettings = userSettingsDao.save(userSettings);
|
||||
|
||||
logger.info("User: "+getLoggedInIdentity()+ " logged in to "+this.getApplication().getClass().getSimpleName()+
|
||||
" as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames()+ " at: "+new Date());
|
||||
loggedIn = true;
|
||||
return loggedIn;
|
||||
}
|
||||
/**
|
||||
* Switch currently logged in user (basically a poor mans 'su') to someone else, the currently logged in user has to be registered as an admin for this to succeed.
|
||||
* Also, the new user has to exist in local database tables or it will fail.
|
||||
* @param suUser
|
||||
* @param suRealm
|
||||
* @return true if the switch was successful, else false.
|
||||
*/
|
||||
public boolean switchAuthenticatedUser(final String suUser, final String suRealm){
|
||||
logger.info("Currently logged in user: '"+user.getEmailAddress()+"' attempting switch to '"+suUser+"'");
|
||||
if(suUser != null && roleDao.isSysadmin(user)){
|
||||
iRoles.clear();
|
||||
return signInAuthenticatedUser(suUser, suRealm);
|
||||
}else{
|
||||
logger.error("User does not have the privilege to switch user");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void logout()
|
||||
{
|
||||
loggedIn = false;
|
||||
@ -123,96 +225,18 @@ public class SciProSession extends WebSession {
|
||||
public synchronized final boolean isLoggedIn() {
|
||||
return loggedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses normal Wicket/JAAS stuff to authenticate a user/password combination.
|
||||
* @param username
|
||||
* @param password
|
||||
* @return true if authentication succeeds, else false.
|
||||
* @throws NullPointerException
|
||||
* @throws FailedLoginException
|
||||
*/
|
||||
private synchronized boolean authenticate(String username, final String password) throws NullPointerException, FailedLoginException {
|
||||
Authenticator auth = new Authenticator();
|
||||
/*
|
||||
* An administrator can log in as a different user in the system by using 'adminusername::otherusername' for login
|
||||
*/
|
||||
String[] tmp = username.split("::");
|
||||
String loggedInAsUsername = null;
|
||||
if(tmp.length > 0){
|
||||
username = tmp[0];
|
||||
if(tmp.length > 1)
|
||||
loggedInAsUsername = tmp[1];
|
||||
}
|
||||
try {
|
||||
try{
|
||||
auth.authenticate(username, password);
|
||||
this.user = userDao.getUserByUsername(username);
|
||||
if( user == null){
|
||||
try{
|
||||
user = doUserLookup(username);
|
||||
if(user == null){
|
||||
throw new NullPointerException("No user with username "+username+" found in the database, or in daisy, despite successful authentication ");
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setLoggedInIdentity(username+"@"+"dsv.su.se");
|
||||
if(user.getEmailAddress() == null || user.getEmailAddress().trim().equals("")){
|
||||
user.setEmailAddress(getLoggedInIdentity());
|
||||
user = userDao.save(user);
|
||||
}
|
||||
/*
|
||||
* Here we switch the logged in user to be that of the person chosen be the logged-in-as by a sysadmin
|
||||
*/
|
||||
|
||||
if(loggedInAsUsername != null && roleDao.isSysadmin(user)){
|
||||
user = userDao.getUserByUsername(loggedInAsUsername);
|
||||
if( user == null){
|
||||
try{
|
||||
user = doUserLookup(loggedInAsUsername);
|
||||
if(user == null){
|
||||
throw new NullPointerException("No user with username "+loggedInAsUsername+" found in the database, or in daisy, despite successful authentication ");
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(roleDao.isStudent(user)){
|
||||
iRoles.add(new Student());
|
||||
}
|
||||
if(roleDao.isExternal(user)){
|
||||
iRoles.add(new External());
|
||||
}
|
||||
if(roleDao.isEmployee(user)){
|
||||
iRoles.add(new Employee());
|
||||
}
|
||||
if(roleDao.isAdmin(user)){
|
||||
iRoles.add(new Admin());
|
||||
}
|
||||
if(roleDao.isSysadmin(user)){
|
||||
iRoles.add(new SysAdmin());
|
||||
}
|
||||
|
||||
if(iRoles.isEmpty()){
|
||||
iRoles.add(new DefaultRole());
|
||||
}
|
||||
/*
|
||||
* Set active project from users settings
|
||||
*/
|
||||
UserSettings userSettings = userSettingsDao.getUserSettings(user);
|
||||
if(userSettings != null){
|
||||
Project activeProject = userSettings.getActiveProject();
|
||||
if(activeProject != null)
|
||||
activeProjectId = activeProject.getId();
|
||||
}
|
||||
else {
|
||||
userSettings = new UserSettings(user);
|
||||
}
|
||||
/*
|
||||
* With this userSettings.created() will return a users first login date and userSettings.modified() will return last login
|
||||
*/
|
||||
userSettings.setLastModified(new Date());
|
||||
userSettings = userSettingsDao.save(userSettings);
|
||||
|
||||
Logger logger = Logger.getLogger("Application");
|
||||
logger.log(Level.INFO, "User: "+getLoggedInIdentity()+ " logged in to "+this.getApplication().getClass().getSimpleName()+
|
||||
" as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames()+ " at: "+new Date());
|
||||
return true;
|
||||
} catch (FailedLoginException e) {
|
||||
//e.printStackTrace();
|
||||
|
179
src/main/java/se/su/dsv/scipro/security/auth/ExternalAuthenticationRequestHelper.java
Normal file
179
src/main/java/se/su/dsv/scipro/security/auth/ExternalAuthenticationRequestHelper.java
Normal file
@ -0,0 +1,179 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import java.security.Policy.Parameters;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.data.dataobjects.Username;
|
||||
|
||||
/**
|
||||
* Helper class for performing authentication via request-headers.
|
||||
* Typical usage:
|
||||
* <code>
|
||||
* helper = new ExternalAuthentificationRequestHelper(request);
|
||||
* if(helper.isExternalAuthSupported() && helper.signIn(session))
|
||||
* success();
|
||||
* else
|
||||
* fail();
|
||||
* </code>
|
||||
* @author robi-ekl
|
||||
*
|
||||
*/
|
||||
public final class ExternalAuthenticationRequestHelper{
|
||||
//Wrapped request
|
||||
private final HttpServletRequest req;
|
||||
//remote user attribute
|
||||
private String remoteUser;
|
||||
//if remote user is on the username@realm form, this attribute holds the username
|
||||
private String remoteUserId;
|
||||
//if remote user is on the username@realm form, this attribute holds the realm
|
||||
private String remoteUserRealm;
|
||||
//logger instance
|
||||
private Logger logger = Logger.getLogger(this.getClass());
|
||||
/**
|
||||
* Construct a utility wrapper from a servlet request.
|
||||
* @param request
|
||||
*/
|
||||
public ExternalAuthenticationRequestHelper(final HttpServletRequest request){
|
||||
req = request;
|
||||
formatUserString();
|
||||
}
|
||||
/**
|
||||
* Exposed query method.
|
||||
* @return The remote user as retrieved from the request, null if none exists.
|
||||
*/
|
||||
public String getExternalAuthRemoteUser(){
|
||||
return remoteUser;
|
||||
}
|
||||
/**
|
||||
* Exposed query method.
|
||||
* @return If remote user is on the username@realm form, this attribute holds the userid, else getExternalAuthRemoteUser().
|
||||
*/
|
||||
public String getExternalAuthRemoteUserId(){
|
||||
return remoteUserId;
|
||||
}
|
||||
/**
|
||||
* Exposed query method.
|
||||
* @return If remote user is on the username@realm form, this attribute holds the realm, else null.
|
||||
*/
|
||||
public String getExternalAuthRemoteUserRealm(){
|
||||
return remoteUserRealm;
|
||||
}
|
||||
/**
|
||||
* Internal query method
|
||||
*/
|
||||
private boolean isExternalAuthInfoOnRequest(){
|
||||
return (req.getRemoteUser()!=null);
|
||||
}
|
||||
/**
|
||||
* Internal query method
|
||||
*/
|
||||
private String getExternalAuthType(){
|
||||
return req.getAuthType();
|
||||
}
|
||||
/**
|
||||
* Query method.
|
||||
* @return true if the application is configured to accept external authentication and the needed information is available on the request, else false.
|
||||
*/
|
||||
public boolean isExternalAuthSupported(){
|
||||
return (true && isExternalAuthInfoOnRequest());
|
||||
}
|
||||
/**
|
||||
* Private utility method for dumping headers.
|
||||
*/
|
||||
public void dumpAuthInfo(){
|
||||
logger.debug("---Standard methods---");
|
||||
logger.debug("Request implementation:" + req.getClass().getName());
|
||||
logger.debug("getAuthType = '" + getExternalAuthType() +"'");
|
||||
logger.debug("getRemoteUser = '"+getExternalAuthRemoteUser()+"'");
|
||||
logger.debug("---Scanning explicitly named attributes---");
|
||||
final String[] params = {"Shib-Application-ID","Shib-Session-ID","Shib-Identity-Provider",
|
||||
"Shib-Authentication-Instant","Shib-Authentication-Method","Shib-AuthnContext-Class","Shib-AuthnContext-Decl","REMOTE_USER","HTTP_REMOTE_USER"};
|
||||
for(final String param:params){
|
||||
logger.debug("getParameter'"+param+"' = '"+req.getParameter(param)+"'");
|
||||
logger.debug("getHeader'"+param+"' = '"+req.getHeader(param)+"'");
|
||||
logger.debug("getAttribute'"+param+"' = '"+req.getAttribute(param)+"'");
|
||||
}
|
||||
{
|
||||
logger.debug("---Iterating over all attributes, parameters, headers and ENV-variables---");
|
||||
logger.debug("All available attributes: ");
|
||||
@SuppressWarnings("rawtypes") Enumeration attributes = req.getAttributeNames();
|
||||
while(attributes.hasMoreElements()){
|
||||
String name = (String)attributes.nextElement();
|
||||
logger.debug("\t'"+name+"' = '"+req.getAttribute(name)+"'");
|
||||
}
|
||||
}
|
||||
{
|
||||
logger.debug("All available parameters: ");
|
||||
@SuppressWarnings("rawtypes") Enumeration parameters = req.getParameterNames();
|
||||
while(parameters.hasMoreElements()){
|
||||
String name = (String)parameters.nextElement();
|
||||
logger.debug("\t'"+name+"' = '"+req.getParameter(name)+"'");
|
||||
}
|
||||
}
|
||||
{
|
||||
logger.debug("All available headers: ");
|
||||
@SuppressWarnings("rawtypes") Enumeration headers = req.getHeaderNames();
|
||||
while(headers.hasMoreElements()){
|
||||
String name = (String)headers.nextElement();
|
||||
logger.debug("\t'"+name+"' = '"+req.getHeader(name)+"'");
|
||||
}
|
||||
}
|
||||
{
|
||||
logger.debug("All available ENV-variables:");
|
||||
Map<String,String> envs = System.getenv();
|
||||
for(String key : envs.keySet()){
|
||||
logger.debug("'"+key+"' = '"+envs.get(key)+"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Query method for checking the validity of a User against this wrapped request.
|
||||
* @param user
|
||||
* @return true if the user matches that on the request, false if not.
|
||||
*/
|
||||
public boolean isRemoteUserValid(final User user){
|
||||
if(user != null && isExternalAuthSupported()){
|
||||
final Set<Username> usernames = user.getUserNames();
|
||||
for(final Username username:usernames){
|
||||
if(username.getUserName().equals(getExternalAuthRemoteUserId()) && username.getRealm().equals(getExternalAuthRemoteUserRealm())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Private utility method.
|
||||
*/
|
||||
private void formatUserString(){
|
||||
remoteUser = req.getRemoteUser();
|
||||
if(remoteUser != null && remoteUser.contains("@")){
|
||||
String[] split = remoteUser.split("@");
|
||||
remoteUserId = split[0];
|
||||
remoteUserRealm = split[1].toUpperCase();
|
||||
}else{
|
||||
remoteUserId = remoteUser;
|
||||
remoteUserRealm = "DSV.SU.SE";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Signs the stored remote user in on the given SciProSession.
|
||||
* @param session
|
||||
* @return true on success, else false.
|
||||
*/
|
||||
public boolean signIn(final SciProSession session){
|
||||
if(session != null){
|
||||
//dumpAuthInfo();
|
||||
return session.signInAuthenticatedUser(getExternalAuthRemoteUserId(), getExternalAuthRemoteUserRealm());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Throw-away implementation of a servlet filter, main task is to fake the getRemoteUser() call for the request chain.
|
||||
*/
|
||||
public final class MockRemoteUserFilter implements Filter {
|
||||
private Logger logger = Logger.getLogger(this.getClass());
|
||||
//Default value unless supplied via init parameter
|
||||
private String fakedUser = "SOME_GUY";
|
||||
private FilterConfig cfg = null;
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public MockRemoteUserFilter() {
|
||||
}
|
||||
/**
|
||||
* @see Filter#destroy()
|
||||
*/
|
||||
public void destroy() {
|
||||
cfg = null;
|
||||
}
|
||||
/**
|
||||
* Wraps the passed request and alters the behavior of getRemoteUser() for later links of the chain.
|
||||
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
logger.info("Faking external authentication user: "+fakedUser);
|
||||
if(cfg != null){
|
||||
HttpServletRequestWrapper wrapper = new ModifiedRemoteUserRequestWrapper((HttpServletRequest)request,fakedUser);
|
||||
// pass the request along the filter chain
|
||||
chain.doFilter(wrapper, response);
|
||||
return;
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
/**
|
||||
* @see Filter#init(FilterConfig)
|
||||
*/
|
||||
public void init(FilterConfig fConfig) throws ServletException {
|
||||
cfg = fConfig;
|
||||
if(cfg!=null){
|
||||
fakedUser = cfg.getInitParameter("fakedUser");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Private RequestWrapper, of no interest to anyone outside of this class.
|
||||
*/
|
||||
class ModifiedRemoteUserRequestWrapper extends HttpServletRequestWrapper{
|
||||
private final String fakedUser;
|
||||
ModifiedRemoteUserRequestWrapper(final HttpServletRequest request,final String fakedUser){
|
||||
super(request);
|
||||
this.fakedUser = fakedUser;
|
||||
}
|
||||
@Override
|
||||
public String getRemoteUser(){
|
||||
return fakedUser;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n
|
||||
log4j.appender.Stdout.layout.conversionPattern=%d{HH:mm:ss,SSS}[%p] - %c{1} - %m\n
|
||||
|
||||
log4j.rootLogger=INFO,Stdout
|
||||
|
||||
@ -8,5 +8,3 @@ log4j.logger.wicket=INFO
|
||||
log4j.logger.wicket.protocol.http.HttpSessionStore=INFO
|
||||
log4j.logger.wicket.version=INFO
|
||||
log4j.logger.wicket.RequestCycle=INFO
|
||||
|
||||
|
||||
|
@ -10,11 +10,29 @@
|
||||
<filter-name>osiv</filter-name>
|
||||
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>osiv</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<!-- Filter for faking an authenticated REMOTE_USER, should never be used in a production environment-->
|
||||
<!-- filter>
|
||||
<description>
|
||||
</description>
|
||||
<display-name>MockRemoteUserFilter</display-name>
|
||||
<filter-name>MockRemoteUserFilter</filter-name>
|
||||
<filter-class>se.su.dsv.scipro.security.auth.MockRemoteUserFilter</filter-class>
|
||||
<init-param>
|
||||
<description>
|
||||
</description>
|
||||
<param-name>fakedUser</param-name>
|
||||
<param-value>robi-ekl@dsv.su.se</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>MockRemoteUserFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping-->
|
||||
|
||||
<filter>
|
||||
<filter-name>wicket.WicketWarp</filter-name>
|
||||
@ -24,11 +42,9 @@
|
||||
<param-value>se.su.dsv.scipro.SciProApplication</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>wicket.WicketWarp</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
|
||||
<!-- These to be able to enable a non-standard not found page -->
|
||||
<dispatcher>REQUEST</dispatcher>
|
||||
<dispatcher>ERROR</dispatcher>
|
||||
|
Loading…
x
Reference in New Issue
Block a user