Wicket Security Wasp & Swarm
Introduction Maurice Marrink Topicus Core Healthcare Education Finance Using Wicket since 2004
History Wasp Swarm Examples Simple setup Custom actions Secure models Questions? Agenda
History
Pre Wicket: Jaas 2004 Wicket POC authentication only 2005 Custom Wicket for authorization 2006 Wicket: IAuthorizationStrategy 2006 Wicket-Jaas internal project 2007 Wasp and Swarm
WASP
Wicket Abstract Security Platform Action based Authentication and Authorization Flexible base Support classes Java 1.4 Wicket 1.3
1 Permission for instantiation or authorization? 2a Authorization permission? 3a Authenticated and or authorized? 3b Custom security checks. 3c Check model. 2b Authorization permission?  4a Authenticated and or authorized? 4b Custom security checks. 3c Wicket Wasp strategy ISecurity Check ISecureModel Security implemen-tation Custom security check 1 2a 2b 3a 3b 4a 4b
Implement ISecurePage Instantiation + login redirect Add ISecurityCheck Or add ISecureModel Or use an ISecureComponent Authorization and or Authentication
SWARM
Standard Wicket Authentication and Rights Management Based on Wasp ACL based Session scope Easy to use with dynamic roles Jaas like security implementation Subjects Principals Permissions Actions Policy files
grant principal nl.example.Principal "basic" { permission ${ComponentPermission} "${myPackage}.SomePage", "inherit, render"; };
Simple setup Example
Extend SwarmWebApplication Create Principal(s) Write policy files
public class App extends SwarmWebApplication { public Class<HomePage> getHomePage(){ return HomePage.class; } public Class<LoginPage> getLoginPage(){ return LoginPage.class; } protected Object getHiveKey(){ return getServletContext().getContextPath(); } …
protected void setUpHive(){ PolicyFileHiveFactory factory = new  PolicyFileHiveFactory(); factory.setAlias(&quot;package&quot;, &quot;nl.example&quot;); try{ factory.addPolicyFile(getServletContext() .getResource(&quot;/WEB-INF/beheer.hive&quot;)); } ... HiveMind. registerHive(getHiveKey(), factory); }
public class MyPrincipal implements Principal{ private String name; public MyPrincipal(String name){ this.name = name; } public String getName(){ return name; } public boolean implies(Subject subject){ return false; } … }
Design your Pages Implement ISecurePage Add security checks Or add secure models Or use secure component
 
 
grant principal ${package}.MyPrincipal  &quot;instelling.deelnemers&quot; { permission ${ComponentPermission} &quot;${package}.SearchPage&quot;, &quot;inherit, render&quot;; permission ${ComponentPermission} &quot;${package}.SearchPage&quot;, &quot;enable&quot;; permission ${ComponentPermission} &quot;${package}.detailPage&quot;, &quot;inherit, render&quot;; permission ${ComponentPermission} &quot;${package}.detailPage&quot;, &quot;enable&quot;; };
Design login page Extend LoginContext Populate Subject with Principals
Wicket Security Example: Simple setup
public boolean signIn(String username, String  password, Domain domain){ LoginContext ctx = new  MyLoginContext(username, password, domain);  try{ ((WaspSession)Session.get()).login(ctx); return true; } catch (LoginException e){ error(e.getMessage()); } return false; }
public Subject login() throws LoginException{ Account accnt = authenticate(username,  password, domain); if (accnt != null){ clearFields(); return new MySubject(accnt); } clearFields(); throw new LoginException(“...”); }
public class MySubject extends DefaultSubject{ public MySubject(Account account){ for (Role role : account.getRoles()){ for (MyPrincipal principal: role.getPrincipals()) addPrincipal(principal); } setReadOnly(); } }
Custom actions Example
Should Divide authorization in levels Direct logic of custom security checks Should not Roles User groups
1 Component and render or enable action 2a Same 3a Custom actions? Wicket Wasp strategy ISecurity Check Security implemen-tation 1 2a 3a
Create Actions Register Actions Use Actions in security check or secure model
 
register(Teacher.class, “teacher&quot;);  register(Counselor.class, “counselor&quot;); register(Location.class, new SomeAction( “ location“, Teacher.class, Counselor.class)); register(School.class, new SomeAction( “ school“, Location.class)); public interface School extends WaspAction { // no explicit implementation required }
public boolean isActionAuthorized(WaspAction action){ WaspAction combined = null, additional; ActionFactory factory = getActionFactory(); for (Class< ? extends WaspAction> actionClass : actions){ additional = factory.getAction(actionClass); combined = action.add(additional); if (wrapped.isActionAuthorized(combined)) return verify(additional); } return false; } protected abstract boolean verify(WaspAction action);
protected boolean verify(WaspAction action){ if (action.implies(getAction(School.class))) return student.getSchool() .equals(getUser().getSchool()); if (action.implies(getAction(Location.class))) return student.takesClassesAt(getUser() .getLocations()); if(…….) ……… . return false; }
Secure models Example
Can In ListViews and other Repeaters In DropDownChoices Reuse of security without declaring it on every Component Can NOT As instantiation check
 
public interface ISecureModel extends IModel { public boolean isAuthorized(Component c, WaspAction a); public boolean isAuthenticated(Component c); } public interface SwarmModel extends ISecureModel { public String getSecurityId(Component c); }
Implement SwarmModel Add DataPermission to policy file
public final String getSecurityId(Component component){ return “foo”; } public boolean isAuthenticated(Component component){ return getStrategy().isModelAuthenticated(this, component); } public boolean isAuthorized(Component component, WaspAction action){ return getStrategy().isModelAuthorized(this, component, action); } protected List<Location> load(){ if (isAuthorized(null, getAction(Instelling.class))){ … } else if (isAuthorized(null, getAction(OrganisatieEenheid.class))){ … } }
grant principal ${package}.MyPrincipal “something&quot; { permission ${DataPermission} “foo”, &quot;render, school&quot;; };
More information: http://wicketstuff.org/confluence/display/STUFFWIKI/Wicket-Security Questions?

Wicket Security Presentation

  • 1.
  • 2.
    Introduction Maurice MarrinkTopicus Core Healthcare Education Finance Using Wicket since 2004
  • 3.
    History Wasp SwarmExamples Simple setup Custom actions Secure models Questions? Agenda
  • 4.
  • 5.
    Pre Wicket: Jaas2004 Wicket POC authentication only 2005 Custom Wicket for authorization 2006 Wicket: IAuthorizationStrategy 2006 Wicket-Jaas internal project 2007 Wasp and Swarm
  • 6.
  • 7.
    Wicket Abstract SecurityPlatform Action based Authentication and Authorization Flexible base Support classes Java 1.4 Wicket 1.3
  • 8.
    1 Permission forinstantiation or authorization? 2a Authorization permission? 3a Authenticated and or authorized? 3b Custom security checks. 3c Check model. 2b Authorization permission? 4a Authenticated and or authorized? 4b Custom security checks. 3c Wicket Wasp strategy ISecurity Check ISecureModel Security implemen-tation Custom security check 1 2a 2b 3a 3b 4a 4b
  • 9.
    Implement ISecurePage Instantiation+ login redirect Add ISecurityCheck Or add ISecureModel Or use an ISecureComponent Authorization and or Authentication
  • 10.
  • 11.
    Standard Wicket Authenticationand Rights Management Based on Wasp ACL based Session scope Easy to use with dynamic roles Jaas like security implementation Subjects Principals Permissions Actions Policy files
  • 12.
    grant principal nl.example.Principal&quot;basic&quot; { permission ${ComponentPermission} &quot;${myPackage}.SomePage&quot;, &quot;inherit, render&quot;; };
  • 13.
  • 14.
    Extend SwarmWebApplication CreatePrincipal(s) Write policy files
  • 15.
    public class Appextends SwarmWebApplication { public Class<HomePage> getHomePage(){ return HomePage.class; } public Class<LoginPage> getLoginPage(){ return LoginPage.class; } protected Object getHiveKey(){ return getServletContext().getContextPath(); } …
  • 16.
    protected void setUpHive(){PolicyFileHiveFactory factory = new PolicyFileHiveFactory(); factory.setAlias(&quot;package&quot;, &quot;nl.example&quot;); try{ factory.addPolicyFile(getServletContext() .getResource(&quot;/WEB-INF/beheer.hive&quot;)); } ... HiveMind. registerHive(getHiveKey(), factory); }
  • 17.
    public class MyPrincipalimplements Principal{ private String name; public MyPrincipal(String name){ this.name = name; } public String getName(){ return name; } public boolean implies(Subject subject){ return false; } … }
  • 18.
    Design your PagesImplement ISecurePage Add security checks Or add secure models Or use secure component
  • 19.
  • 20.
  • 21.
    grant principal ${package}.MyPrincipal &quot;instelling.deelnemers&quot; { permission ${ComponentPermission} &quot;${package}.SearchPage&quot;, &quot;inherit, render&quot;; permission ${ComponentPermission} &quot;${package}.SearchPage&quot;, &quot;enable&quot;; permission ${ComponentPermission} &quot;${package}.detailPage&quot;, &quot;inherit, render&quot;; permission ${ComponentPermission} &quot;${package}.detailPage&quot;, &quot;enable&quot;; };
  • 22.
    Design login pageExtend LoginContext Populate Subject with Principals
  • 23.
  • 24.
    public boolean signIn(Stringusername, String password, Domain domain){ LoginContext ctx = new MyLoginContext(username, password, domain); try{ ((WaspSession)Session.get()).login(ctx); return true; } catch (LoginException e){ error(e.getMessage()); } return false; }
  • 25.
    public Subject login()throws LoginException{ Account accnt = authenticate(username, password, domain); if (accnt != null){ clearFields(); return new MySubject(accnt); } clearFields(); throw new LoginException(“...”); }
  • 26.
    public class MySubjectextends DefaultSubject{ public MySubject(Account account){ for (Role role : account.getRoles()){ for (MyPrincipal principal: role.getPrincipals()) addPrincipal(principal); } setReadOnly(); } }
  • 27.
  • 28.
    Should Divide authorizationin levels Direct logic of custom security checks Should not Roles User groups
  • 29.
    1 Component andrender or enable action 2a Same 3a Custom actions? Wicket Wasp strategy ISecurity Check Security implemen-tation 1 2a 3a
  • 30.
    Create Actions RegisterActions Use Actions in security check or secure model
  • 31.
  • 32.
    register(Teacher.class, “teacher&quot;); register(Counselor.class, “counselor&quot;); register(Location.class, new SomeAction( “ location“, Teacher.class, Counselor.class)); register(School.class, new SomeAction( “ school“, Location.class)); public interface School extends WaspAction { // no explicit implementation required }
  • 33.
    public boolean isActionAuthorized(WaspActionaction){ WaspAction combined = null, additional; ActionFactory factory = getActionFactory(); for (Class< ? extends WaspAction> actionClass : actions){ additional = factory.getAction(actionClass); combined = action.add(additional); if (wrapped.isActionAuthorized(combined)) return verify(additional); } return false; } protected abstract boolean verify(WaspAction action);
  • 34.
    protected boolean verify(WaspActionaction){ if (action.implies(getAction(School.class))) return student.getSchool() .equals(getUser().getSchool()); if (action.implies(getAction(Location.class))) return student.takesClassesAt(getUser() .getLocations()); if(…….) ……… . return false; }
  • 35.
  • 36.
    Can In ListViewsand other Repeaters In DropDownChoices Reuse of security without declaring it on every Component Can NOT As instantiation check
  • 37.
  • 38.
    public interface ISecureModelextends IModel { public boolean isAuthorized(Component c, WaspAction a); public boolean isAuthenticated(Component c); } public interface SwarmModel extends ISecureModel { public String getSecurityId(Component c); }
  • 39.
    Implement SwarmModel AddDataPermission to policy file
  • 40.
    public final StringgetSecurityId(Component component){ return “foo”; } public boolean isAuthenticated(Component component){ return getStrategy().isModelAuthenticated(this, component); } public boolean isAuthorized(Component component, WaspAction action){ return getStrategy().isModelAuthorized(this, component, action); } protected List<Location> load(){ if (isAuthorized(null, getAction(Instelling.class))){ … } else if (isAuthorized(null, getAction(OrganisatieEenheid.class))){ … } }
  • 41.
    grant principal ${package}.MyPrincipal“something&quot; { permission ${DataPermission} “foo”, &quot;render, school&quot;; };
  • 42.