0

ZK and Spring Security integration- questions

asked 2009-02-15 17:39:12 +0800

davout gravatar image davout
1435 3 18
I'm building a management information system app using ZK and I want to integrate with the Spring Security module. I've read the short articles on this site and can't find the answers there, so I'm posting these questions in the hope that somebody c
delete flag offensive retag edit

13 Replies

Sort by ยป oldest newest

answered 2009-02-15 23:48:22 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2009-02-16 10:27:29 +0800

@davout i read these articles too and the spring sec Guide (2.04). At time i worked with a borderlayout in the index.zul page So i have at every time the same url when i call a new Page showing in the layout center area. Therefore the url-based sec
link publish delete flag offensive edit

answered 2009-02-16 06:39:10 +0800

davout gravatar image davout
1435 3 18

Thanks for your response and help.

My app is the same as yours - a single URL with changing content within a central data pane.

There was one question left unanswered. Spring Security works by intercepting a call to a secured area and displaying the login form. How and what do you call if a user wants to login themselves directly from controls on the main page? Is there an 'authenticate()' method I can call somewhere inside Spring Security and how would that generate the same session based data that the intercept approach creates?

link publish delete flag offensive edit

answered 2009-02-16 11:04:50 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2009-02-16 11:11:27 +0800

@davout

i'm not at place. Can send code first in 7 hours. But

Firstly i have a non secured index.zul ( WebContent/index.zul )outside my application pages /WEB-INF/pages/*.zul.
On these side i have a button 'go to the application'.
When a user clicks on the button a 'href=/pages/index.zul' requests to the secured folder area where my app pages resides.
These secured area is defined in the applicationSecurityContext.xml in the <http tag
and defines the logout url, form-login, intercept-url.

<intercept-url pattern="/pages/** access="IS_AUTHENTICATED_REMEBERED" />
<intercept-url pattern="/WEB-INF/pages/** access="IS_AUTHENTICATED_REMEBERED" />
<intercept-url pattern="/** access="IS_AUTHENTICATED_ANONYMOUSLY" />

So you do not make explizit a login, you make a try to call a real page (index.zu) that is secured by a folder area ("/pages/** ")in the xml-file and Spring-Security intercepts this call and go to the login-page if the user are not logged in. Spring remembers if a user is logged in.
So explizit, i have a LOGOUT button. That makes a href to the spring-security logout-url. And spring manage the rest: Clears the UserDetails, GrantedAuthorities... and redirect (if configured) to a logout-success-url ="/index.zul" (the non-secured page) and the circle begins new.

regards
Stephan

I will post this evening sample codes.

link publish delete flag offensive edit

answered 2009-02-16 14:42:35 +0800

davout gravatar image davout
1435 3 18

Your design to different to how my app will work. My starting URL/page remains the only URL used by the app. Hence, there is no jump to "/pages..." like you describe.

With my design the user can remain anomymous (un authenticated) until they either...
* Try to do something (add or edit data) that requires an identity
* They themselves decide to login. This is where I'm struggling.

However, I'm trying to keep the design flexible so that a deployment may set the security configuration where up front login/authentication is required.

Thoughts?

link publish delete flag offensive edit

answered 2009-02-16 21:16:40 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2009-02-16 21:19:30 +0800

@davout

I'm thinking about your needs.

1. When a user is reaching your site you can create a logged-in user manually with the rights he need for have a look at all.
2. When he will press a secured button you can intercept this in code.

sample-code


   ...
   public void onClick$btnEdit(Event event) {

          // "btnEdit" is a RIGHT
      if ( isAllowed("btnEdit")) {

           doEdit();

       } else {
         
         Executions.sendRedirect("/LoginDialog.zul");
         
        }
      }

  ...

	/**
	 * Checks if a right is in the <b>granted rights</b> that the logged in user
	 * have. <br>
	 * 
	 * @param rightName
	 * @return true, if the right is in the granted user rights.<br>
	 *         false, if the right is not granted to the user.<br>
	 */
	public boolean isAllowed(String rightName) {
		return getGrantedAuthoritySet().contains(rightName);
	}

   ...


	/**
	 * Copied the grantedAuthorities to a Set of strings <br>
	 * for a faster searching in it.
	 * 
	 * @return String set of GrantedAuthorities (rightNames)
	 */
	private Set<String> getGrantedAuthoritySet() {

		if (grantedAuthoritySet == null) {

			GrantedAuthority[] list = getAuthentication().getAuthorities();
			grantedAuthoritySet = new HashSet<String>(list.length);

			for (GrantedAuthority grantedAuthority : list) {
				grantedAuthoritySet.add(grantedAuthority.getAuthority());
			}
		}
		return grantedAuthoritySet;
	}




Hope this helps
Stephan

link publish delete flag offensive edit

answered 2009-02-16 22:41:20 +0800

alexmanly gravatar image alexmanly
45 1

updated 2009-02-16 22:43:29 +0800

I have done this by importing a taglib I have created which contains security and utility methods.

This ZUL file declares the tag library and uses the methods to test security role levels:

<?taglib uri="/WEB-INF/tld/web/myutil.tld" prefix="util" ?>

<zul:grid oddRowSclass="none">
   <zul:columns>
      <zul:column align="right" width="50%"/>
      <zul:column align="left" width="50%"/>
   </zul:columns>
   <zul:rows>
      <zul:row if="${util:isAdministrator()}">
         <zul:label value="You have the role: ${util:sf('com.mycompany.security.SecurityService.ADMINISTRATOR')}."/>
         <zul:button label="View Secure Administrators Page" href="${util:sf('com.mycompany.Navigation.ADMIN_PAGE')}"/>
      </zul:row>
   </zul:rows>
</zul:grid>

This is the tag lib definition:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib>
	<description>My Tag Library</description>
	    
    <function>
        <name>isAdministrator</name>
        <function-class>com.company.service.security.SecurityService</function-class>
        <function-signature>
    		boolean isAdministrator()
        </function-signature>
        <description></description>
    </function>
        
    <function>
        <name>userHasAuthority</name>
        <function-class>org.springframework.security.util.AuthorityUtils</function-class>
        <function-signature>
    		boolean userHasAuthority(java.lang.String authority)
        </function-signature>
        <description></description>
    </function>
    
    <function>
        <name>sf</name>
        <function-class>com.company.helper.Helper</function-class>
        <function-signature>
    		java.lang.String getStaticField(java.lang.String name)
        </function-signature>
        <description></description>
    </function>

</taglib>

Here are the tag lib method implementations:

In SecurityService.java

        public static final String ADMINISTRATOR = "ROLE_ADMINISTRATOR";

	public static boolean isAdministrator() {
		return org.springframework.security.util.AuthorityUtils.userHasAuthority(SecurityService.ADMINISTRATOR);
	}

In Helper.java

	public static String getStaticField(String name) {
		try {
			int i = name.lastIndexOf(".");
			String field = name.substring(i + 1, name.length());
			name = name.substring(0, i);
			Object obj = Class.forName(name).getField(field).get(null);
			if (obj != null) {
				return obj.toString();
			}
			return null;
		} catch (Exception x) {
			throw new RuntimeException(x);
		}
	}

This is the static field which is referenced as the href of the secured buton:
In Navigation.java

        public static final String ADMIN_PAGE = "/spring/secure/admin/extremelysecure";

link publish delete flag offensive edit

answered 2009-02-17 10:13:05 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2009-02-17 10:13:44 +0800

@alexmanly

this is a fine work for zkoss.

Only, i would have problems with this code:
<zul:row if="${util:isAdministrator()}">

If there is a need for adding Roles you must edit the code!
If you have several applications running by different customers so your codebase is running away in different versions. To avoid the developer for this i go the way with a fixed single rightname for a secured button/method/page/tab and so on.
The assigning of these rights to roles or groups and users are done visually and stored in tables.

regards
Stephan

link publish delete flag offensive edit

answered 2009-02-18 08:00:29 +0800

davout gravatar image davout
1435 3 18

Thank you all for your contributions, but I think there is a weakness in the general approach being outlined, i.e.
* a user tries some action
* the code checks that the user is allowed to perform the action
* the code either continues with the action or rejects it

The weakness lies in the fact that the user should only be allowed to select actions for which they have authorization rights. In otherwords the GUI tier should only display options that the user is entitled to complete, and conversely hide any GUI elements where they lack the correct rights. Anything less is counter intuitive and frustrating for the user.

From this I'd say that the ZK GUI tier needs to include both tags and code to support this notion of pre-checking for authorization and using these checks to show/hide GUI components.

Are there any Spring Security tags available that do this stuff already? If not, I'd appreciate some pointers on how to build it.

I'm thinking here of a tag like...

   <security:granted  role="administrator" />
   <security:notgranted role="user,guest" />


Then have matching code that can used with the ZK 'if' tag attribute.

Thoughts?

link publish delete flag offensive edit

answered 2009-02-18 10:36:12 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2009-02-18 10:41:42 +0800

@davout

it's all at your hands.

Sample:
At time my mainMenu Tree checks in the onCreateMenuController() which menu items are shown by the rights that a user have.

  ...
   private Tree treeMainMenu; // autowire
   private Treecell homeMenu; // autowire
   private Treecell menuCat_OfficeData; // autowire
   ...


  public void onCreate$mainMenuWindow(Event event) throws Exception {
  ...
  checkUserRights();
  }

   private void ceckUserRights() {

     // get the user specific workspace
     UserWorkspace workspace = UserWorkspace.getInstance();

     // Home menu. Not secured
     homeMenu.setVisible(true);
     homeMenu.addEventListener("onClick", new treeCellClickEventListener());


     // Menu Category
     if (workspace.isAllowed("menuCat_OfficeData")){
        menuCat_OfficeData.setVusible(true);

        // Menu item CUSTOMER
        if (workspace.isAllowed("menuItem_OfficeData_Customers")){
           menuItem_OfficeData_Customers.setVusible(true);
           menuItem_OfficeData_Customers.addEventListener("onClick", new 
                                            treeCellClickEventListener());
        }

        // Menu item ORDERS
        if (workspace.isAllowed("menuItem_OfficeData_Orders")){
           menuItem_OfficeData_Orders.setVusible(true);
           menuItem_OfficeData_Orders.addEventListener("onClick", new 
                                            treeCellClickEventListener());
        }
    }

       // Menu Category
       if (workspace.isAl...{}
       ...
  }

   /**
   * Inner class. EventHandling for the onClick of the menuItems
   */
   public class treeCellClickEventListener implements org.zkos. ...EventListener {
     public void onEvent(Event event) throws UIException {
         doMenuItem(event.getTarget());
        } catch (Exception e){
          //TODO: Handle e
         }
      }
   }


  private void doMenuItem(Component comp) throws InterruptedException {

    // get the zul-file components id
    String menuItemID = comp.getId();

    if (menuitem == null){
      return;
    } else if (menuitemID.isEmpty()) {
      Messagebox.show("MenuItem is missing!")
      }
 
    if(menuItemID.equalsIgnoreCase("HomeMenu")){
      // Welcome Page
      showPage("/WEB-INF/pages/welcome.zul")
    } else if (menuItemID.equalsIgnoreCase("menuItem_OfficeData_Customers")){
      // Office Data Category menuItem: Customers
      showPage("/WEB-INF/pages/customerList.zul")
    } else if (menuItemID.equalsIgnoreCase("menuItem_OfficeData_Orders")){
      // Office Data Category menuItem: Orders
      showPage("/WEB-INF/pages/orderList.zul")
    ...
     }
}

   /**
   * creates the page from the zul-file and put it in the
   * CENTER area of the borderlayout
   */
   private void showPage(String zulFilePathName){
     try {
       /* get an instance of the borderlayout defined in the zul-file */
       Borderlayout bl = (Borderlayout) Path.getComponent("outerIndexWindow/borderlayoutMain");
       /* get an instance of the CENTER layout area */
       Center center = bl.getCenter();
       center.setFlex();
       /* clear the child comps */
       center.getChilfren().clear();
       /* create the page and put it in the center area */
       Executions.createComponents(zulFilePathName, center, null);

     } catch (Exception e) {
       Messagebox.show(e);
     }



}




   }


link publish delete flag offensive edit

answered 2010-03-16 03:26:55 +0800

zkman gravatar image zkman
78

Hi!
I use Spring in my application. I looked thorough zkoss-v2-0 and zkspringsec3 examples. All of them use redirection to another page after success logon. But I want to return to the page from which I start the login dialog window. And do this with some event - for example: do visible the logout button. I try to use "login-ok-url" and execute some procedure in this zul file. But I got the error - access denied, button <logout> belongs to another desktop, though I use sessionScope to save and reuse my main class instance which procedure I try to execute in "login-ok-url" zul file.
So can you advise how to fire an event in main page when login is successful?

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2009-02-15 17:39:12 +0800

Seen: 1,183 times

Last updated: Mar 20 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More