Ej helt färdigställd roll och autentiseringshantering men all grundfunktionalitet finns. Saknar bekvämlighetsmetoder för att ställa in roller på enskilda komponenter, saknar helt SAML/Schibbolet-integration, saknar databas/entityrepresentation av roller.
git-svn-id: svn://svn.dsv.su.se/scipro/scipro/trunk@9 73ecded7-942e-4092-bab0-0e58ef0ee984
This commit is contained in:
parent
93b9aa93ef
commit
0171b2d9ab
src/main/java/se/su/dsv/scipro
HomePage.javaSciProApplication.javaSciProSession.java
basepages
data
loginlogout/pages
pages
security/auth
@ -4,13 +4,16 @@ import org.apache.wicket.PageParameters;
|
||||
import org.apache.wicket.markup.html.WebPage;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
|
||||
import se.su.dsv.scipro.basepages.BasePage;
|
||||
import se.su.dsv.scipro.basepages.PublicPage;
|
||||
import se.su.dsv.scipro.pages.EventPage;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
|
||||
/**
|
||||
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
*
|
||||
*/
|
||||
public class HomePage extends WebPage {
|
||||
public class HomePage extends PublicPage {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
@ -6,12 +6,16 @@ import org.apache.wicket.Page;
|
||||
import org.apache.wicket.Request;
|
||||
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.spring.injection.annot.SpringComponentInjector;
|
||||
|
||||
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
|
||||
import se.su.dsv.scipro.loginlogout.pages.LogoutPage;
|
||||
import se.su.dsv.scipro.pages.EventPage;
|
||||
import se.su.dsv.scipro.security.auth.ComponentSecurityLogger;
|
||||
import se.su.dsv.scipro.security.auth.MetaDataActionStrategy;
|
||||
import se.su.dsv.scipro.security.auth.RoleBasedAuthorizationStrategy;
|
||||
|
||||
/**
|
||||
* Application object for your web application. If you want to run this application without deploying, run the Start class.
|
||||
@ -53,6 +57,13 @@ public class SciProApplication extends WebApplication {
|
||||
mountBookmarkablePage("logout", LogoutPage.class);
|
||||
|
||||
addComponentInstantiationListener(getSpringInjector());
|
||||
|
||||
CompoundAuthorizationStrategy cas = new CompoundAuthorizationStrategy();
|
||||
cas.add(new RoleBasedAuthorizationStrategy());
|
||||
cas.add(new MetaDataActionStrategy());
|
||||
getSecuritySettings().setAuthorizationStrategy(cas);
|
||||
|
||||
getSecuritySettings().setUnauthorizedComponentInstantiationListener(new ComponentSecurityLogger());
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package se.su.dsv.scipro;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.security.auth.login.FailedLoginException;
|
||||
@ -15,9 +17,17 @@ import org.apache.wicket.protocol.http.WebRequest;
|
||||
import org.apache.wicket.protocol.http.WebSession;
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
|
||||
import se.su.dsv.scipro.auth.Authenticator;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.security.auth.Authenticator;
|
||||
import se.su.dsv.scipro.security.auth.roles.Admin;
|
||||
import se.su.dsv.scipro.security.auth.roles.DefaultRole;
|
||||
import se.su.dsv.scipro.security.auth.roles.Employee;
|
||||
import se.su.dsv.scipro.security.auth.roles.External;
|
||||
import se.su.dsv.scipro.security.auth.roles.Role;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
import se.su.dsv.scipro.security.auth.roles.Student;
|
||||
import se.su.dsv.scipro.security.auth.roles.SysAdmin;
|
||||
|
||||
|
||||
|
||||
@ -30,7 +40,7 @@ public class SciProSession extends WebSession {
|
||||
@SpringBean
|
||||
private UserDao userDao;
|
||||
|
||||
//private List<Role> roles = new ArrayList<Role>();
|
||||
private List<Role> roles = new ArrayList<Role>();
|
||||
private User user = null;
|
||||
|
||||
private String loggedInIdentity = null;
|
||||
@ -119,36 +129,39 @@ public class SciProSession extends WebSession {
|
||||
/*
|
||||
* Here we switch the logged in user to be that of the person chosen be the logged in admin
|
||||
*/
|
||||
/*
|
||||
|
||||
if(userDao.isAdmin(user) && loggedInAsUsername != null){
|
||||
this.user = userDao.getUserByUserName(loggedInAsUsername);
|
||||
this.user = userDao.getUserByUsername(loggedInAsUsername);
|
||||
if( user == null)
|
||||
throw new NullPointerException("No user with this username found in the database, despite successful authentication");
|
||||
|
||||
throw new NullPointerException("No user with this username found in the database, despite successful authentication");
|
||||
}
|
||||
if(userDao.isAuthor(user)){
|
||||
rolesString = rolesString +"AUTHOR,";
|
||||
roles.add(new AuthorRole());
|
||||
if(userDao.isStudent(user)){
|
||||
roles.add(new Student());
|
||||
}
|
||||
if(userDao.isSupervisor(user)){
|
||||
rolesString = rolesString +"SUPERVISOR,";
|
||||
roles.add(new SupervisorRole());
|
||||
if(userDao.isExternal(user)){
|
||||
roles.add(new External());
|
||||
}
|
||||
if(userDao.isEmployee(user)){
|
||||
roles.add(new Employee());
|
||||
}
|
||||
if(userDao.isAdmin(user)){
|
||||
rolesString = rolesString +"ADMIN,";
|
||||
roles.add(new AdminRole());
|
||||
roles.add(new Admin());
|
||||
}
|
||||
if(userDao.isSysadmin(user)){
|
||||
roles.add(new SysAdmin());
|
||||
}
|
||||
|
||||
if(roles.isEmpty()){
|
||||
roles.add(new DefaultRole());
|
||||
}
|
||||
*/
|
||||
|
||||
Logger logger = Logger.getLogger("Application");
|
||||
logger.log(Level.INFO, "User: "+getLoggedInIdentity()+ " logged in as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames());
|
||||
return true;
|
||||
} catch (FailedLoginException e) {
|
||||
//e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
} catch (LoginException e) {
|
||||
//e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -157,6 +170,13 @@ public class SciProSession extends WebSession {
|
||||
public String toString(){
|
||||
return loggedInIdentity;//+" Roles: "+rolesString;
|
||||
}
|
||||
|
||||
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
for(Role existingRole : roles){
|
||||
if(existingRole.authorizedForRole(role))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,10 @@ import org.apache.wicket.PageParameters;
|
||||
import org.apache.wicket.markup.html.CSSPackageResource;
|
||||
import org.apache.wicket.markup.html.WebPage;
|
||||
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
@Authorization(requiresLoggedInUser = true, authorizedRoles = {Roles.STUDENT, Roles.ADMIN, Roles.EMPLOYEE, Roles.EXTERNAL, Roles.SYSADMIN})
|
||||
public abstract class BasePage extends WebPage {
|
||||
|
||||
public BasePage(){
|
||||
@ -14,12 +18,9 @@ public abstract class BasePage extends WebPage {
|
||||
super(pp);
|
||||
}
|
||||
|
||||
public static String ADMIN_CSS = "admin";
|
||||
public static String SUPERVISOR_CSS = "supervisor";
|
||||
public static String AUTHOR_CSS = "author";
|
||||
public static String GLOBAL_CSS = "global";
|
||||
public static String POPUP_CSS = "popup";
|
||||
public static String CSS_SUFFIX = ".css";
|
||||
public final static String GLOBAL_CSS = "global";
|
||||
public final static String POPUP_CSS = "popup";
|
||||
public final static String CSS_SUFFIX = ".css";
|
||||
|
||||
protected void setCss(String css){
|
||||
String languageCode = "";
|
||||
|
18
src/main/java/se/su/dsv/scipro/basepages/PublicPage.java
Normal file
18
src/main/java/se/su/dsv/scipro/basepages/PublicPage.java
Normal file
@ -0,0 +1,18 @@
|
||||
package se.su.dsv.scipro.basepages;
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
|
||||
@Authorization(requiresLoggedInUser = false)
|
||||
public abstract class PublicPage extends BasePage {
|
||||
|
||||
public PublicPage(){
|
||||
super();
|
||||
}
|
||||
|
||||
public PublicPage(PageParameters pp){
|
||||
super(pp);
|
||||
}
|
||||
|
||||
}
|
@ -10,5 +10,14 @@ public interface UserDao extends LazyDeleteDao<User> {
|
||||
|
||||
public User getUserByEmail(final String emailAddress);
|
||||
|
||||
public boolean isStudent(final User user);
|
||||
|
||||
public boolean isExternal(final User user);
|
||||
|
||||
public boolean isEmployee(final User user);
|
||||
|
||||
public boolean isAdmin(final User user);
|
||||
|
||||
public boolean isSysadmin(final User user);
|
||||
|
||||
}
|
||||
|
@ -67,4 +67,29 @@ public class UserDaoJPAImp extends LazyDeleteAbstractDaoJPAImpl<User> implements
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isStudent(final User user) {
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isExternal(final User user) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEmployee(final User user) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAdmin(final User user) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSysadmin(final User user) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import javax.persistence.Table;
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name="Event")
|
||||
@Table(name="event")
|
||||
public class Event extends DomainObject {
|
||||
|
||||
private static final long serialVersionUID = 2959377496669050427L;
|
||||
|
@ -18,7 +18,7 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name="User")
|
||||
@Table(name="user")
|
||||
@Cacheable(true)
|
||||
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific
|
||||
public class User extends LazyDeletableDomainObject {
|
||||
|
@ -19,7 +19,7 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
@Entity
|
||||
@Cacheable(true)
|
||||
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific
|
||||
@Table(name="Username", uniqueConstraints={@UniqueConstraint(columnNames={"username","realm"})})
|
||||
@Table(name="username", uniqueConstraints={@UniqueConstraint(columnNames={"username","realm"})})
|
||||
public class Username extends DomainObject {
|
||||
|
||||
private static final long serialVersionUID = -2043481766263425696L;
|
||||
|
@ -5,7 +5,7 @@ import org.apache.wicket.RestartResponseException;
|
||||
|
||||
import se.su.dsv.scipro.HomePage;
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.basepages.BasePage;
|
||||
import se.su.dsv.scipro.basepages.PublicPage;
|
||||
import se.su.dsv.scipro.loginlogout.panels.LoginPanel;
|
||||
|
||||
/**
|
||||
@ -13,16 +13,10 @@ import se.su.dsv.scipro.loginlogout.panels.LoginPanel;
|
||||
* @param pp the page parameters
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
*/
|
||||
public class LoginPage extends BasePage {
|
||||
public class LoginPage extends PublicPage {
|
||||
|
||||
public LoginPage(final PageParameters pp) throws Exception {
|
||||
|
||||
//Redirect to HomePage if user is authenticated
|
||||
if(SciProSession.get().isLoggedIn()){
|
||||
getRequestCycle().setRedirect(true);
|
||||
throw new RestartResponseException(HomePage.class);
|
||||
}
|
||||
|
||||
|
||||
add(new LoginPanel("signInPanel", true));
|
||||
|
||||
}
|
||||
|
@ -5,14 +5,13 @@ import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.basepages.BasePage;
|
||||
import se.su.dsv.scipro.basepages.PublicPage;
|
||||
|
||||
public class LogoutPage extends BasePage {
|
||||
public class LogoutPage extends PublicPage {
|
||||
|
||||
public LogoutPage(final PageParameters parameters){
|
||||
SciProSession session = SciProSession.get();
|
||||
|
||||
session.invalidate();
|
||||
SciProSession.get().invalidate();
|
||||
|
||||
add(new Label("message", "You are now logged out. Log back in "));
|
||||
BookmarkablePageLink<Void> bml = new BookmarkablePageLink<Void>("loginLink", LoginPage.class);
|
||||
|
@ -16,23 +16,35 @@ import org.apache.wicket.model.CompoundPropertyModel;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
|
||||
import se.su.dsv.scipro.basepages.BasePage;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Event;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.Authorization.ON_AUTH_FAIL;
|
||||
import se.su.dsv.scipro.security.auth.ComponentSecurity;
|
||||
import se.su.dsv.scipro.security.auth.MetaDataActionStrategy;
|
||||
import se.su.dsv.scipro.security.auth.SecurityFailAction;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
import se.su.dsv.scipro.security.auth.roles.Student;
|
||||
/**
|
||||
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
|
||||
*
|
||||
*/
|
||||
public class EventPage extends WebPage {
|
||||
public class EventPage extends BasePage {
|
||||
|
||||
@SpringBean
|
||||
private EventDao eventDao;
|
||||
|
||||
Form<Event> eventForm;
|
||||
|
||||
public EventPage(final PageParameters pp)
|
||||
{
|
||||
Form<Event> eventForm = new Form<Event>("eventForm", new CompoundPropertyModel<Event>(new Event()));
|
||||
eventForm = new Form<Event>("eventForm", new CompoundPropertyModel<Event>(new Event()));
|
||||
eventForm.add(new TextField<String>("title").setRequired(true));
|
||||
eventForm.add(new TextField<String>("location").setRequired(true));
|
||||
|
||||
eventForm.setMetaData(MetaDataActionStrategy.AUTHORIZED_ROLES, new ComponentSecurity(Roles.EMPLOYEE, SecurityFailAction.DISABLE));
|
||||
|
||||
final WebMarkupContainer wmc = new WebMarkupContainer("listContainer");
|
||||
|
||||
wmc.add(new ListView<Event>("list", new PropertyModel<List<Event>>(this, "eventDao.findAll")){
|
||||
@ -68,4 +80,5 @@ public class EventPage extends WebPage {
|
||||
add(eventForm);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package se.su.dsv.scipro.auth;
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import javax.security.auth.login.FailedLoginException;
|
||||
import javax.security.auth.login.LoginContext;
|
@ -0,0 +1,40 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
/**
|
||||
*
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
* @author Niklas Herder for base code
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface Authorization {
|
||||
|
||||
enum ON_AUTH_FAIL {
|
||||
/**
|
||||
* Disable the component, but show
|
||||
*/
|
||||
DISABLE_COMPONENT,
|
||||
/**
|
||||
* Hide the component
|
||||
*/
|
||||
HIDE_COMPONENT,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Which action to take on this component when authorization fails.
|
||||
*/
|
||||
ON_AUTH_FAIL actionOnAuthFail() default ON_AUTH_FAIL.HIDE_COMPONENT;
|
||||
|
||||
/**
|
||||
* Whether the component requires a logged in user
|
||||
*/
|
||||
boolean requiresLoggedInUser() default true;
|
||||
|
||||
Roles[] authorizedRoles() default {Roles.SYSADMIN};
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
/**
|
||||
*
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
*
|
||||
*/
|
||||
public class ComponentSecurity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final ArrayList<Roles> authorizedRoles = new ArrayList<Roles>();
|
||||
private SecurityFailAction failAction;
|
||||
|
||||
public ComponentSecurity(Roles role){
|
||||
this(role, SecurityFailAction.REMOVE);
|
||||
}
|
||||
|
||||
public ComponentSecurity(Roles role, SecurityFailAction action){
|
||||
authorizedRoles.add(role);
|
||||
if( action == null )
|
||||
throw new IllegalArgumentException("FailAction may not be null");
|
||||
failAction = action;
|
||||
}
|
||||
|
||||
public ComponentSecurity(Roles[] roles){
|
||||
this(roles, SecurityFailAction.REMOVE);
|
||||
}
|
||||
|
||||
public ComponentSecurity(Roles[] roles, SecurityFailAction action) {
|
||||
authorizedRoles.addAll(Arrays.asList(roles));
|
||||
if( action == null )
|
||||
throw new IllegalArgumentException("FailAction may not be null");
|
||||
failAction = action;
|
||||
}
|
||||
|
||||
public SecurityFailAction getFailAction(){
|
||||
return failAction;
|
||||
}
|
||||
|
||||
public List<Roles> getAuthorizedRoles(){
|
||||
//For security-concerns we don't return the mutable list but a copy
|
||||
return new ArrayList<Roles>(authorizedRoles);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.RestartResponseAtInterceptPageException;
|
||||
import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;
|
||||
|
||||
import se.su.dsv.scipro.SciProApplication;
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
/**
|
||||
*
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
*
|
||||
*/
|
||||
public class ComponentSecurityLogger implements IUnauthorizedComponentInstantiationListener {
|
||||
|
||||
public void onUnauthorizedInstantiation(Component component) {
|
||||
Logger logger = Logger.getLogger("Application");
|
||||
logger.log(Level.WARN, "User: "+SciProSession.get().getLoggedInIdentity()+ " attempted to instantiate unauthorized page: "+component.getClass());
|
||||
throw new RestartResponseAtInterceptPageException(SciProApplication.get().getApplicationSettings().getAccessDeniedPage());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package se.su.dsv.scipro.auth;
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.security.auth.callback.Callback;
|
@ -0,0 +1,61 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.MetaDataKey;
|
||||
import org.apache.wicket.authorization.Action;
|
||||
import org.apache.wicket.authorization.IAuthorizationStrategy;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
/**
|
||||
*
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
* Checks for actionAuthorization of components based on component-metadata
|
||||
*/
|
||||
public class MetaDataActionStrategy implements IAuthorizationStrategy {
|
||||
|
||||
public static final MetaDataKey<ComponentSecurity> AUTHORIZED_ROLES = new MetaDataKey<ComponentSecurity>() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
};
|
||||
|
||||
public boolean isActionAuthorized(final Component component, final Action action) {
|
||||
//Get metadata from component, if none return true for any action
|
||||
ComponentSecurity cs = component.getMetaData(AUTHORIZED_ROLES);
|
||||
if( cs != null ){
|
||||
//Check if user is authorized for this role
|
||||
List<Roles> authorizedRoles = cs.getAuthorizedRoles();
|
||||
for(Roles role : authorizedRoles){
|
||||
if(SciProSession.get().authorizedForRole(role))
|
||||
return true;
|
||||
}
|
||||
//If we've left the loop without a return then handle different kinds of failure
|
||||
if(action.equals(Component.RENDER)){
|
||||
if( cs.getFailAction().equals(SecurityFailAction.REMOVE))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else if(action.equals(Component.ENABLE)){
|
||||
//A value of ENABLE = false should be the only logical option left at this point
|
||||
return false;
|
||||
/* If more fail actions were implemented consider this code
|
||||
if(cs.getFailAction().equals(SecurityFailAction.DISABLE))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
*/
|
||||
} else
|
||||
throw new IllegalStateException("Should be unreachable code, someone broke something! Unrecognized action: "+action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public <T extends Component> boolean isInstantiationAuthorized(final Class<T> arg0) {
|
||||
// Doesn't care about instantiation, only cares about action authorization
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.RestartResponseAtInterceptPageException;
|
||||
import org.apache.wicket.authorization.Action;
|
||||
import org.apache.wicket.authorization.IAuthorizationStrategy;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
/**
|
||||
*
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
* @author Niklas Herder for inspiration
|
||||
*/
|
||||
public class RoleBasedAuthorizationStrategy implements IAuthorizationStrategy {
|
||||
|
||||
public boolean isActionAuthorized(Component component, Action action) {
|
||||
|
||||
boolean ok = false;
|
||||
Class<? extends Component> authRequired = null;
|
||||
if (component instanceof BookmarkablePageLink<?>) {
|
||||
//If it's a link: check permissions for the component the link refers to.
|
||||
BookmarkablePageLink<?> bookmarkablePageLink = (BookmarkablePageLink<?>) component;
|
||||
authRequired = bookmarkablePageLink.getPageClass();
|
||||
} else {
|
||||
//Otherwise check auth for the compoenent
|
||||
authRequired = component.getClass();
|
||||
}
|
||||
//Get the annotation from the class if there is one
|
||||
Authorization annotation = authRequired.getAnnotation(Authorization.class);
|
||||
//Not annotated classes aren't checked further
|
||||
if( annotation == null)
|
||||
ok = true;
|
||||
else {
|
||||
//Check if it's a "public page" or not
|
||||
if ( !annotation.requiresLoggedInUser() )
|
||||
ok = true;
|
||||
else {
|
||||
//Check for presence of login and if present check for authorization
|
||||
if( SciProSession.get().isLoggedIn() ){//&& annotation.authorizedRoles().length > 0){ If no roles added, ok will be false
|
||||
for( Roles role : annotation.authorizedRoles() ){
|
||||
if( SciProSession.get().authorizedForRole(role) ){
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//If not ok so far check what to do on fail
|
||||
if(!ok){
|
||||
if(action.equals(Component.RENDER)){
|
||||
if( annotation.actionOnAuthFail() == Authorization.ON_AUTH_FAIL.HIDE_COMPONENT)
|
||||
ok = false;
|
||||
else
|
||||
ok = true;
|
||||
} else if (action.equals(Component.ENABLE)){
|
||||
if( annotation.actionOnAuthFail() == Authorization.ON_AUTH_FAIL.DISABLE_COMPONENT)
|
||||
ok = false;
|
||||
else
|
||||
ok = true;
|
||||
} else
|
||||
throw new IllegalStateException("Action "+action.getName()+ " is unknown");
|
||||
}//Auth failed, what to do on fail?
|
||||
}//There was an annotation present
|
||||
|
||||
//TODO: Remove this println
|
||||
System.out.println("RoleBasedAuthorisationStrategy says authorized: "+ok+" for action "+action.getName()+" on component "+component.getClass());
|
||||
return ok;
|
||||
}
|
||||
|
||||
public <T extends Component> boolean isInstantiationAuthorized(Class<T> componentClass) {
|
||||
|
||||
//Not annotated classes aren't checked further
|
||||
Authorization annotation = (Authorization) componentClass.getAnnotation(Authorization.class);
|
||||
if (annotation != null) {
|
||||
|
||||
//If component doesn't require login anyone may do it any time
|
||||
if( !annotation.requiresLoggedInUser() )
|
||||
return true;
|
||||
//If page requires login and user isn't logged in, send them to login page first
|
||||
if( annotation.requiresLoggedInUser() && !SciProSession.get().isLoggedIn())
|
||||
throw new RestartResponseAtInterceptPageException(LoginPage.class);
|
||||
//Check the users role for authorization to instantiate the component
|
||||
for(Roles role : annotation.authorizedRoles()){
|
||||
if( SciProSession.get().authorizedForRole(role) )
|
||||
return true;
|
||||
}
|
||||
//No roles were added to the annotation or user was not authorized for the roles that were added
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package se.su.dsv.scipro.security.auth;
|
||||
/**
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
* @author Niklas Herder for inspiration
|
||||
* Enumeration of different actions to take when the actionAuthorization fails on a component
|
||||
*/
|
||||
public enum SecurityFailAction {
|
||||
/*
|
||||
* Disable a component, makes links unclickable, buttons 'grey' etc.
|
||||
*/
|
||||
DISABLE,
|
||||
/*
|
||||
* Completely removes components instead of rendering them
|
||||
*/
|
||||
REMOVE
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public class Admin extends DefaultRole {
|
||||
|
||||
@Override
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
switch(role) {
|
||||
case SYSADMIN:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Admin";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public class DefaultRole implements Role {
|
||||
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public class Employee extends DefaultRole {
|
||||
|
||||
@Override
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
switch(role) {
|
||||
case EMPLOYEE:
|
||||
return true;
|
||||
case EXTERNAL:
|
||||
return true;
|
||||
case STUDENT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Employee";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public class External extends DefaultRole {
|
||||
|
||||
@Override
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
switch(role) {
|
||||
case EXTERNAL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "External";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public interface Role {
|
||||
|
||||
public boolean authorizedForRole(Roles role);
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public enum Roles {
|
||||
|
||||
/*
|
||||
* For students
|
||||
*/
|
||||
STUDENT,
|
||||
/*
|
||||
* Externals could be given supervisional roles but no administrative rights
|
||||
*/
|
||||
EXTERNAL,
|
||||
/*
|
||||
* Employees people might have some administrative rights and may have supervisional roles
|
||||
*/
|
||||
EMPLOYEE,
|
||||
/*
|
||||
* Can do most things
|
||||
*/
|
||||
ADMIN,
|
||||
/*
|
||||
* Can do everything
|
||||
*/
|
||||
SYSADMIN
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public class Student extends DefaultRole {
|
||||
|
||||
@Override
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
switch(role) {
|
||||
case STUDENT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package se.su.dsv.scipro.security.auth.roles;
|
||||
|
||||
public class SysAdmin extends DefaultRole {
|
||||
|
||||
@Override
|
||||
public boolean authorizedForRole(Roles role) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SysAdmin";
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user