SlideShare ist ein Scribd-Unternehmen logo
1 von 29
Downloaden Sie, um offline zu lesen
KAAccessControl
A framework for easy user access control.	

Samuel Pelletier
Why ?
• All apps require some user right management.	

• Creating permission management is boring and may be tedious.	

• A basic implementation always need refactoring after new
modules are added to an application.	

• I'm lazy and prefer to use a proved model and limit code
required in a new app.	

• I do not like having to rewrite non app specific code all the time.
Some history
• Basic principles (Roles and Lists) used since 2003 in PHP apps.	

• First implementation of the model in PHP in 2006 for a central
user management system used by many php apps.	

• The model can manage all private apps I worked on.	

• First WebObjects implementation in 2011.	

• Complete rewrite in 2013 for easier integration.
Do / don't do
• Manage user access rights and include a permission editor UI
component.	

• Manage component access rights with annotation.	

• Support territory or other data segmentation needs with list
associated to role.	

• Do not provide authentication but includes password hashing
classes you may use.	

• Probably too complex for a public accessible site or app.
Definition: List
• List are used to segment data or access right.	

• List are usually linked to another entity of the application like
territory, division, warehouse, department, ...	

• A list contains items; a territory list may contain north America,
south America, Europe and Asia for example.	

• Items are used to specify with part of the data is relevant for a
user; a manager for the north and south Americas for example.
Definition: Role
• Role are the base permission unit. 	

• Used to define what a user can do; a user has roles.	

• Used to define who can access a component; a component is
accessible by user with a specified role.	

• Role can be qualified by item from list for data segmentation; a
salesman role is qualified by territory item(s). used to define
watch a user can do
Definition: Profile
• A profile define a user type; administrator is a common user
profile.	

• A profile is defined by a set of included roles and a set of
optional roles.	

• Profile are used to simplify the user right management. By
selecting a profile for a user, the set of options is limited to
relevant roles.
Definition: User Profile
• A user profile is a complete user access right definition with:	

• A profile with it's included roles and selected role's items,	

• A set of optional roles selected with their role's items.	

• A user can have multiple user profiles but only one is effective
and one is marked as default (selected when the user log in).	

• Multiple user profiles are used for peoples requiring complex
permission with incompatible data segmentation like a
warehouse manager also a sale manager.
UML model
Managed by the
UserPermissionEditor component
or your own permission editor.
Managed by a plist file specified in
properties or manually.
Updated automatically if the list is linked to an entity.
You have to create this entity.id
passwordHash
app specific attributes...
Real user entity
id
roleGroup_id
code
displayOrder
permissionList_id
allowsMultipleItems
KARole
id
code
KAProfile
id
displayOrder
code
KARoleGroup
*
* **
*
id
code
KAAccessList
userProfileRole_id
permissionListItem_id
KAUserProfileRoleItem
id
userProfile_id
role_id
KAUserProfileRole
id
user_id
profile_id
isDefaultProfile
KAUserProfile
profile_id
role_id
isOptionnal
KAProfileRole
*
*
*
*
id
accessList_id
code
KAAccessListItem
*
*
id
passwordHash
KAUser
Using it in a project
• Add the framework to build path.	

• Create the real user entity in your model by selecting the KAUser as parent class.	

• Implements the createHomePageForUserProfile(...) method in your user class.	

• Create the foreign key constraint on KAUserProfile in your migration code.	

• Create the role.plist file.	

• Add some properties.	

• Create your user management components using the provided UserPermissionsEditor.	

• Total time: about 15 minutes for a working skeleton.
New app demo
Framework Properties
• ka.accesscontrol.rolesFile : the name of the plist file with your
role and profile definition.	

• ka.accesscontrol.rolesFileBundle : the name of the framework
containing your roles file. Leave blank if the file is in app bundle.	

• ka.accesscontrol.loggedOutPageName : the name of the
component to return when a user log out.	

• er.migration.migrateAtStartup=true	

• er.migration.modelNames=KAAccessControl,yourModels
In your framework or application Properties file, add:
#Path to the plist file read at startup to updates the frameworks data tables AccessList, RoleGroup, Role and Profile.	
ka.accesscontrol.rolesFile=Roles	
#Name of the framework that contain the plist file, not needed if the file is inside the app bundle.	
ka.accesscontrol.rolesFileBundle=FrameworkName	
!
#Name of the WOComponent to return when a user log out of the system.	
ka.accesscontrol.logedOutPageName=LoggedOut	
!
# Migrations	
er.migration.migrateAtStartup=true	
er.migration.createTablesIfNecessary=true	
er.migration.modelNames=KAAccessControl,YourModelNames...	
!
#Make sure you put KAAccessControl before your migration if you want to 	
# create the foreign key constraint or some bootstrap users.
Some useful addition to your migration class
To create the foreign key constrain in the database, add this line in your migration class:	
!
KAAccessControlMigrationHelper.addForeignKeyAndIndex(database, "YourRealUserTableName");	
!
Make sure the Roles are up to date before creating the first user	
RolesFileLoader.loadRolesFile(editingContext);	
editingContext.saveChanges();	
!
#Bootstrap an admin user.	
#Suppose your real user class is User...	
User admin = ERXEOControlUtilities.createAndInsertObject(editingContext, User.class);	
admin.changePassword("adminPassword");	
admin.defaultUserProfile().setProfileWithCode("Admin");	
!
#Set other mandatory attributes in your User entity...	
admin.setLanguage(User.englishLanguageCode);	
admin.setUsername("admin");	
!
Create the role.plist file (use the sample as template)
{	
lists = (	
	 "Territory",	
	 "Wharehouse"	
);	
roleGroups = (	
	 {	
	 	 code = "Sales";	
	 	 roles = (	
	 	 	 {	
	 	 	 	 code = "CustomerSalesReport";	
	 	 	 	 listCode = "Territory";	
	 	 	 	 allowsMultipleItems = YES;	
	 	 	 },	
	 	 	 {	
	 	 	 	 "code" = "SeeGrossProfits";	
	 	 	 },	
	 	 );	
	 }	
);	
profiles = (	
	 {	
	 	 code = "Salesman";	
	 	 roles = (	
	 	 	 "CustomerSalesReport"	
	 	 );	
	 	 optionalRoles = (	
	 	 	 "SeeGrossProfits"	
	 	 );	
	 }	
);
The User class
	 // This required method create the home page based on the UserProfile selected.	
!
	 @Override	
	 public WOComponent createHomePageForUserProfile(WOContext context, KAUserProfile userProfile) {	
	 	 if (userProfile.profileCode().equals(Profile.Admin)) {	
	 	 	 return ERXApplication.application().pageWithName("UserList", context);	
	 	 }	
	 	 if (userProfile.profileCode().equals(Profile.WharehouseManager)) {	
	 	 	 return ERXApplication.application().pageWithName("WarehouseDashboard", context);	
	 	 }	
	 	 return ERXApplication.application().pageWithName("CustomerList", context);	
	 }
The List, Profile and Role classes
• These classes are not mandatory but highly recommended.	

• Put the list, profile and role code in string constants. 	

• Use these contants for annotations or permission checking in
the code.	

• Using constants helps to reduce typing errors.	

• Eclipse has a nice function to find all references to a constant.
Localization
• Profile name in key "profile.profileCode"	

• Role name in key "role.roleCode"	

• RoleGroup name in key "group.groupCode"	

• Few strings found in the framework Localizable.strings
ListItemAutoUpdater
• Link a list to an entity using a Java annotation.	

• @AutoSyncWithAccessList(listCode="ListCode",
nameProperty=EntityClass.NAME_KEY)	

• List item copy the name returned by the key specified in the
annotation as displayed name on the UI.	

• Retrieve selected items as EOs from a user profile with
itemsAsObjectsForRole(eoClass, roleCode).	

• The system autostart in the framework didFinishInitialization().
Auto synced entity
@AutoSyncWithAccessList(listCode=List.Territory, nameProperty=SaleTerritory.LOCALIZED_NAME_KEY)	
@SuppressWarnings("serial")	
public class SaleTerritory extends com.kaviju.accesscontroldemo.model.base._SaleTerritory {	
	 @SuppressWarnings("unused")	
	 private static Logger log = Logger.getLogger(SaleTerritory.class);	
!
	 static public final String LOCALIZED_NAME_KEY = "localizedName";	
	 static public final ERXKey<String> LOCALIZED_NAME = new ERXKey<String>(LOCALIZED_NAME_KEY);	
!
	 public String localizedName() {	
	 	 if (ERXLocalizer.currentLocalizer().languageCode().equalsIgnoreCase(User.frenchLanguageCode)) {	
	 	 	 return nom();	
	 	 }	
	 	 return name();	
	 }	
}
UserAccessControlService
• Responsible to manage the current userProfile and the personify
stack.	

• Personify allow a user to log as another user, very useful for
technical support.	

• There is a real and current user (usually the same) like in UNIX.	

• The session create the service and pass a delegate for logon
events; usually itself.	

• The delegate receive userProfileDidLogon(userProfile) to
prepare or clean the session for the new active profile.
Session.java
public class Session extends ERXSession implements UserLogonDelegate{	
	 private UserAccessControlService<User> userAccessService;	
!
	 public Session() {	
	 	 userAccessService = new UserAccessControlService<User>(this);	
	 	 setTimeOut(10*60);	
	 	 ...	
	 }	
!
	 @Override	
	 public void userProfileDidLogon(KAUserProfile userProfile) {	
	 	 setLocalizerWithUserLanguage(userProfile.user(User.class));	
	 	 setTimeOut(4*3600);	
	 	 if (Profile.ShortSession.equals(userProfile.profileCode())) {	
	 	 	 setTimeOut(15*60);	
	 	 }	
	 }	
!
	 public void setLocalizerWithUserLanguage(User user) {	
	 	 if (User.frenchLanguageCode.equals(user.language()) ) {	
	 	 	 setLanguage("French");	
	 	 	 shortDateFormatter = new ERXJodaLocalDateFormatter("d MMMM", Locale.CANADA_FRENCH, null);	
	 	 	 	 	 	
	 	 }	
	 	 if (User.englishLanguageCode.equals(user.language()) ) {	
	 	 	 setLanguage("English");	
	 	 	 shortDateFormatter = new ERXJodaLocalDateFormatter("MMMM d", Locale.CANADA, null);
The logon method
	 public WOActionResults logon() {	
	 	 // Fetch the User with your custom attributes.		
	 	 User user = User.fetchUser(session().defaultEditingContext(), User.USERNAME.eq(username()));	
!
	 	 if (user != null && password != null) {	
	 	 	 // Use the PasswordHasher to verify the password and upgrade it to new hasher if required.	
	 	 	 if (user.someAthenticationMethod(password)) {	
	 	 	 	 // Tell the UserAccessControl someone logged in and return the provided home page.	
	 	 	 	 return session().userAccessService().logonAsUser(user);	
	 	 	 }	
	 	 }	
	 	 displayError = true;	
	 	 return null;	
	 }
ComponentAccessService
• This object read the component classes annotation.	

• It is used in the checkAccess() method of your
ERXComponents.
BaseComponent.java
	 @Override	
	 protected void checkAccess() throws SecurityException {	
	 	 if (context().page().equals(this)) {	
	 	 	 ComponentAccessService accessService = ComponentAccessService.getInstance();	
	 	 	 if ( accessService.isComponentAccessibleForUserProfile(getClass(), currentUserProfile()) == false) {	
	 	 	 	 throw new SecurityException("Component "+getClass().getSimpleName()+" require one of these roles "+	
	 	 	 	 	 	 accessService.readAllowedForRolesAnnotationInClass(getClass())+	
	 	 	 	 	 	 " current user "+currentUser()+" have these "+currentUserProfile().allEffectiveRoles());	
	 	 	 }	
	 	 }	
	 	 super.checkAccess();	
	 }	
!
	 public KAUserProfile currentUserProfile() {	
	 	 return session().userAccessService().currentUserProfile();	
	 }	
!
	 public User currentUser() {	
	 	 return session().userAccessService().currentUser();	
	 }	
	 	
	 public boolean isUserAdmin() {	
	 	 String currentUserProfileCode = session().userAccessService().currentUserProfile().profileCode();	
	 	 return currentUserProfileCode.equals(Profile.Admin);	
	 }
Using PasswordHasher
• Currently the framework contains Pbkdf2Hasher and
LatinSimpleMD5Hasher.	

• You can add your Hasher by creating a subclass of
PasswordHasher. 	

• Register knows hasher(s) during application init.	

• Saved hash contains a hasher identifier params and salt.	

• Set the default hasher to use when changing a user password
with KAUser.setCurrentPasswordHasher(hasher).
Using legacy password hashes
• Register a default hasher to use with incomplete hashes using
KAUser.setDefaultPasswordHasher(hasher).	

• The default hasher is used when the current hash for user does
not contains an hasher code.	

• authenticateWithPasswordAndUpgradeHashIfRequired(password)
will upgrade the hash with the current hasher if the password is
verified.	

• This method will upgrade any verified hash to the current hasher.
Next features ?
• New password hashers.	

• Support for LDAP authentication.	

• UI to edit the roles.plist file.	

• Adjustments for WOInject.
Q&A
Samuel Pelletier	

Kaviju inc.	

samuel@kaviju.com	

https://github.com/spelletier

Weitere ähnliche Inhalte

Was ist angesagt?

CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011
Alexander Klimetschek
 
Designing a JavaFX Mobile application
Designing a JavaFX Mobile applicationDesigning a JavaFX Mobile application
Designing a JavaFX Mobile application
Fabrizio Giudici
 
Expression Language in JSP
Expression Language in JSPExpression Language in JSP
Expression Language in JSP
corneliuskoo
 

Was ist angesagt? (20)

CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011
 
Hibernate
Hibernate Hibernate
Hibernate
 
Getting Started with jQuery
Getting Started with jQueryGetting Started with jQuery
Getting Started with jQuery
 
Евгений Капинос "Advanced JPA (Java Persistent API)"
Евгений Капинос "Advanced JPA (Java Persistent API)"Евгений Капинос "Advanced JPA (Java Persistent API)"
Евгений Капинос "Advanced JPA (Java Persistent API)"
 
Solr workshop
Solr workshopSolr workshop
Solr workshop
 
Jstl Guide
Jstl GuideJstl Guide
Jstl Guide
 
Designing a JavaFX Mobile application
Designing a JavaFX Mobile applicationDesigning a JavaFX Mobile application
Designing a JavaFX Mobile application
 
CSharp Advanced L05-Attributes+Reflection
CSharp Advanced L05-Attributes+ReflectionCSharp Advanced L05-Attributes+Reflection
CSharp Advanced L05-Attributes+Reflection
 
Class-based views with Django
Class-based views with DjangoClass-based views with Django
Class-based views with Django
 
Expression Language in JSP
Expression Language in JSPExpression Language in JSP
Expression Language in JSP
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Codegeneration With Xtend
Codegeneration With XtendCodegeneration With Xtend
Codegeneration With Xtend
 
A Dexterity Intro for Recovering Archetypes Addicts
A Dexterity Intro for Recovering Archetypes AddictsA Dexterity Intro for Recovering Archetypes Addicts
A Dexterity Intro for Recovering Archetypes Addicts
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScript
 
Intorduction of Playframework
Intorduction of PlayframeworkIntorduction of Playframework
Intorduction of Playframework
 
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developersSoftshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
 
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
Jquery 4
Jquery 4Jquery 4
Jquery 4
 

Andere mochten auch (17)

High availability
High availabilityHigh availability
High availability
 
Using GIT
Using GITUsing GIT
Using GIT
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnit
 
WOver
WOverWOver
WOver
 
iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative version
 
Reenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSReenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWS
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
 
Using Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsUsing Nagios to monitor your WO systems
Using Nagios to monitor your WO systems
 
Chaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldChaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real World
 
Migrating existing Projects to Wonder
Migrating existing Projects to WonderMigrating existing Projects to Wonder
Migrating existing Projects to Wonder
 
iOS for ERREST
iOS for ERRESTiOS for ERREST
iOS for ERREST
 
Build and deployment
Build and deploymentBuild and deployment
Build and deployment
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful Controllers
 
Advanced Apache Cayenne
Advanced Apache CayenneAdvanced Apache Cayenne
Advanced Apache Cayenne
 
Deploying WO on Windows
Deploying WO on WindowsDeploying WO on Windows
Deploying WO on Windows
 
"Framework Principal" pattern
"Framework Principal" pattern"Framework Principal" pattern
"Framework Principal" pattern
 

Ähnlich wie KAAccessControl

GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
Yared Ayalew
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 

Ähnlich wie KAAccessControl (20)

.Net template solution architecture
.Net template solution architecture.Net template solution architecture
.Net template solution architecture
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplications
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
 
Dexterity in the Wild
Dexterity in the WildDexterity in the Wild
Dexterity in the Wild
 
WOdka
WOdkaWOdka
WOdka
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Field injection, type safe configuration, and more new goodies in Declarative...
Field injection, type safe configuration, and more new goodies in Declarative...Field injection, type safe configuration, and more new goodies in Declarative...
Field injection, type safe configuration, and more new goodies in Declarative...
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Jpa
JpaJpa
Jpa
 
Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)
 
119764860 dx-auth
119764860 dx-auth119764860 dx-auth
119764860 dx-auth
 
Learning to run
Learning to runLearning to run
Learning to run
 
Developing Lightning Components for Communities.pptx
Developing Lightning Components for Communities.pptxDeveloping Lightning Components for Communities.pptx
Developing Lightning Components for Communities.pptx
 
13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS 13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS
 
Overview Of Drupal
Overview Of DrupalOverview Of Drupal
Overview Of Drupal
 
Overview Of Drupal
Overview Of DrupalOverview Of Drupal
Overview Of Drupal
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Java Web Programming on Google Cloud Platform [2/3] : Datastore
Java Web Programming on Google Cloud Platform [2/3] : DatastoreJava Web Programming on Google Cloud Platform [2/3] : Datastore
Java Web Programming on Google Cloud Platform [2/3] : Datastore
 
Struts 2
Struts 2Struts 2
Struts 2
 

Mehr von WO Community (9)

Localizing your apps for multibyte languages
Localizing your apps for multibyte languagesLocalizing your apps for multibyte languages
Localizing your apps for multibyte languages
 
ERGroupware
ERGroupwareERGroupware
ERGroupware
 
D2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerD2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRoller
 
CMS / BLOG and SnoWOman
CMS / BLOG and SnoWOmanCMS / BLOG and SnoWOman
CMS / BLOG and SnoWOman
 
Persistent Session Storage
Persistent Session StoragePersistent Session Storage
Persistent Session Storage
 
Back2 future
Back2 futureBack2 future
Back2 future
 
WebObjects Optimization
WebObjects OptimizationWebObjects Optimization
WebObjects Optimization
 
Dynamic Elements
Dynamic ElementsDynamic Elements
Dynamic Elements
 
Practical ERSync
Practical ERSyncPractical ERSync
Practical ERSync
 

Kürzlich hochgeladen

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Kürzlich hochgeladen (20)

%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 

KAAccessControl

  • 1. KAAccessControl A framework for easy user access control. Samuel Pelletier
  • 2. Why ? • All apps require some user right management. • Creating permission management is boring and may be tedious. • A basic implementation always need refactoring after new modules are added to an application. • I'm lazy and prefer to use a proved model and limit code required in a new app. • I do not like having to rewrite non app specific code all the time.
  • 3. Some history • Basic principles (Roles and Lists) used since 2003 in PHP apps. • First implementation of the model in PHP in 2006 for a central user management system used by many php apps. • The model can manage all private apps I worked on. • First WebObjects implementation in 2011. • Complete rewrite in 2013 for easier integration.
  • 4. Do / don't do • Manage user access rights and include a permission editor UI component. • Manage component access rights with annotation. • Support territory or other data segmentation needs with list associated to role. • Do not provide authentication but includes password hashing classes you may use. • Probably too complex for a public accessible site or app.
  • 5. Definition: List • List are used to segment data or access right. • List are usually linked to another entity of the application like territory, division, warehouse, department, ... • A list contains items; a territory list may contain north America, south America, Europe and Asia for example. • Items are used to specify with part of the data is relevant for a user; a manager for the north and south Americas for example.
  • 6. Definition: Role • Role are the base permission unit. • Used to define what a user can do; a user has roles. • Used to define who can access a component; a component is accessible by user with a specified role. • Role can be qualified by item from list for data segmentation; a salesman role is qualified by territory item(s). used to define watch a user can do
  • 7. Definition: Profile • A profile define a user type; administrator is a common user profile. • A profile is defined by a set of included roles and a set of optional roles. • Profile are used to simplify the user right management. By selecting a profile for a user, the set of options is limited to relevant roles.
  • 8. Definition: User Profile • A user profile is a complete user access right definition with: • A profile with it's included roles and selected role's items, • A set of optional roles selected with their role's items. • A user can have multiple user profiles but only one is effective and one is marked as default (selected when the user log in). • Multiple user profiles are used for peoples requiring complex permission with incompatible data segmentation like a warehouse manager also a sale manager.
  • 9. UML model Managed by the UserPermissionEditor component or your own permission editor. Managed by a plist file specified in properties or manually. Updated automatically if the list is linked to an entity. You have to create this entity.id passwordHash app specific attributes... Real user entity id roleGroup_id code displayOrder permissionList_id allowsMultipleItems KARole id code KAProfile id displayOrder code KARoleGroup * * ** * id code KAAccessList userProfileRole_id permissionListItem_id KAUserProfileRoleItem id userProfile_id role_id KAUserProfileRole id user_id profile_id isDefaultProfile KAUserProfile profile_id role_id isOptionnal KAProfileRole * * * * id accessList_id code KAAccessListItem * * id passwordHash KAUser
  • 10. Using it in a project • Add the framework to build path. • Create the real user entity in your model by selecting the KAUser as parent class. • Implements the createHomePageForUserProfile(...) method in your user class. • Create the foreign key constraint on KAUserProfile in your migration code. • Create the role.plist file. • Add some properties. • Create your user management components using the provided UserPermissionsEditor. • Total time: about 15 minutes for a working skeleton.
  • 12. Framework Properties • ka.accesscontrol.rolesFile : the name of the plist file with your role and profile definition. • ka.accesscontrol.rolesFileBundle : the name of the framework containing your roles file. Leave blank if the file is in app bundle. • ka.accesscontrol.loggedOutPageName : the name of the component to return when a user log out. • er.migration.migrateAtStartup=true • er.migration.modelNames=KAAccessControl,yourModels
  • 13. In your framework or application Properties file, add: #Path to the plist file read at startup to updates the frameworks data tables AccessList, RoleGroup, Role and Profile. ka.accesscontrol.rolesFile=Roles #Name of the framework that contain the plist file, not needed if the file is inside the app bundle. ka.accesscontrol.rolesFileBundle=FrameworkName ! #Name of the WOComponent to return when a user log out of the system. ka.accesscontrol.logedOutPageName=LoggedOut ! # Migrations er.migration.migrateAtStartup=true er.migration.createTablesIfNecessary=true er.migration.modelNames=KAAccessControl,YourModelNames... ! #Make sure you put KAAccessControl before your migration if you want to # create the foreign key constraint or some bootstrap users.
  • 14. Some useful addition to your migration class To create the foreign key constrain in the database, add this line in your migration class: ! KAAccessControlMigrationHelper.addForeignKeyAndIndex(database, "YourRealUserTableName"); ! Make sure the Roles are up to date before creating the first user RolesFileLoader.loadRolesFile(editingContext); editingContext.saveChanges(); ! #Bootstrap an admin user. #Suppose your real user class is User... User admin = ERXEOControlUtilities.createAndInsertObject(editingContext, User.class); admin.changePassword("adminPassword"); admin.defaultUserProfile().setProfileWithCode("Admin"); ! #Set other mandatory attributes in your User entity... admin.setLanguage(User.englishLanguageCode); admin.setUsername("admin"); !
  • 15. Create the role.plist file (use the sample as template) { lists = ( "Territory", "Wharehouse" ); roleGroups = ( { code = "Sales"; roles = ( { code = "CustomerSalesReport"; listCode = "Territory"; allowsMultipleItems = YES; }, { "code" = "SeeGrossProfits"; }, ); } ); profiles = ( { code = "Salesman"; roles = ( "CustomerSalesReport" ); optionalRoles = ( "SeeGrossProfits" ); } );
  • 16. The User class // This required method create the home page based on the UserProfile selected. ! @Override public WOComponent createHomePageForUserProfile(WOContext context, KAUserProfile userProfile) { if (userProfile.profileCode().equals(Profile.Admin)) { return ERXApplication.application().pageWithName("UserList", context); } if (userProfile.profileCode().equals(Profile.WharehouseManager)) { return ERXApplication.application().pageWithName("WarehouseDashboard", context); } return ERXApplication.application().pageWithName("CustomerList", context); }
  • 17. The List, Profile and Role classes • These classes are not mandatory but highly recommended. • Put the list, profile and role code in string constants. • Use these contants for annotations or permission checking in the code. • Using constants helps to reduce typing errors. • Eclipse has a nice function to find all references to a constant.
  • 18. Localization • Profile name in key "profile.profileCode" • Role name in key "role.roleCode" • RoleGroup name in key "group.groupCode" • Few strings found in the framework Localizable.strings
  • 19. ListItemAutoUpdater • Link a list to an entity using a Java annotation. • @AutoSyncWithAccessList(listCode="ListCode", nameProperty=EntityClass.NAME_KEY) • List item copy the name returned by the key specified in the annotation as displayed name on the UI. • Retrieve selected items as EOs from a user profile with itemsAsObjectsForRole(eoClass, roleCode). • The system autostart in the framework didFinishInitialization().
  • 20. Auto synced entity @AutoSyncWithAccessList(listCode=List.Territory, nameProperty=SaleTerritory.LOCALIZED_NAME_KEY) @SuppressWarnings("serial") public class SaleTerritory extends com.kaviju.accesscontroldemo.model.base._SaleTerritory { @SuppressWarnings("unused") private static Logger log = Logger.getLogger(SaleTerritory.class); ! static public final String LOCALIZED_NAME_KEY = "localizedName"; static public final ERXKey<String> LOCALIZED_NAME = new ERXKey<String>(LOCALIZED_NAME_KEY); ! public String localizedName() { if (ERXLocalizer.currentLocalizer().languageCode().equalsIgnoreCase(User.frenchLanguageCode)) { return nom(); } return name(); } }
  • 21. UserAccessControlService • Responsible to manage the current userProfile and the personify stack. • Personify allow a user to log as another user, very useful for technical support. • There is a real and current user (usually the same) like in UNIX. • The session create the service and pass a delegate for logon events; usually itself. • The delegate receive userProfileDidLogon(userProfile) to prepare or clean the session for the new active profile.
  • 22. Session.java public class Session extends ERXSession implements UserLogonDelegate{ private UserAccessControlService<User> userAccessService; ! public Session() { userAccessService = new UserAccessControlService<User>(this); setTimeOut(10*60); ... } ! @Override public void userProfileDidLogon(KAUserProfile userProfile) { setLocalizerWithUserLanguage(userProfile.user(User.class)); setTimeOut(4*3600); if (Profile.ShortSession.equals(userProfile.profileCode())) { setTimeOut(15*60); } } ! public void setLocalizerWithUserLanguage(User user) { if (User.frenchLanguageCode.equals(user.language()) ) { setLanguage("French"); shortDateFormatter = new ERXJodaLocalDateFormatter("d MMMM", Locale.CANADA_FRENCH, null); } if (User.englishLanguageCode.equals(user.language()) ) { setLanguage("English"); shortDateFormatter = new ERXJodaLocalDateFormatter("MMMM d", Locale.CANADA, null);
  • 23. The logon method public WOActionResults logon() { // Fetch the User with your custom attributes. User user = User.fetchUser(session().defaultEditingContext(), User.USERNAME.eq(username())); ! if (user != null && password != null) { // Use the PasswordHasher to verify the password and upgrade it to new hasher if required. if (user.someAthenticationMethod(password)) { // Tell the UserAccessControl someone logged in and return the provided home page. return session().userAccessService().logonAsUser(user); } } displayError = true; return null; }
  • 24. ComponentAccessService • This object read the component classes annotation. • It is used in the checkAccess() method of your ERXComponents.
  • 25. BaseComponent.java @Override protected void checkAccess() throws SecurityException { if (context().page().equals(this)) { ComponentAccessService accessService = ComponentAccessService.getInstance(); if ( accessService.isComponentAccessibleForUserProfile(getClass(), currentUserProfile()) == false) { throw new SecurityException("Component "+getClass().getSimpleName()+" require one of these roles "+ accessService.readAllowedForRolesAnnotationInClass(getClass())+ " current user "+currentUser()+" have these "+currentUserProfile().allEffectiveRoles()); } } super.checkAccess(); } ! public KAUserProfile currentUserProfile() { return session().userAccessService().currentUserProfile(); } ! public User currentUser() { return session().userAccessService().currentUser(); } public boolean isUserAdmin() { String currentUserProfileCode = session().userAccessService().currentUserProfile().profileCode(); return currentUserProfileCode.equals(Profile.Admin); }
  • 26. Using PasswordHasher • Currently the framework contains Pbkdf2Hasher and LatinSimpleMD5Hasher. • You can add your Hasher by creating a subclass of PasswordHasher. • Register knows hasher(s) during application init. • Saved hash contains a hasher identifier params and salt. • Set the default hasher to use when changing a user password with KAUser.setCurrentPasswordHasher(hasher).
  • 27. Using legacy password hashes • Register a default hasher to use with incomplete hashes using KAUser.setDefaultPasswordHasher(hasher). • The default hasher is used when the current hash for user does not contains an hasher code. • authenticateWithPasswordAndUpgradeHashIfRequired(password) will upgrade the hash with the current hasher if the password is verified. • This method will upgrade any verified hash to the current hasher.
  • 28. Next features ? • New password hashers. • Support for LDAP authentication. • UI to edit the roles.plist file. • Adjustments for WOInject.