Navigator 7: Change `#` character in URIs

Hi All,

Is it possible to change the ‘#’ character in the urls that Navigator 7 uses when navigating between pages??

i.e. so
http://domain.com/appName/#user/userid=555 becomes something like
http://domain.com/appName/user/userid=555 or even
http://domain.com/appName/Xuser/userid=555

I’ve tried overriding buildFragmentFromPageAndParameters in the UriAnalyzer class, but it seems ‘withAnchor’ parameter is always false, so it doesn’t add the ‘#’ character anyway. But its still there…

Thanks,

Stuart.

Are you aware that # has a special meaning in an URL? (I have to ask, since I don’t know your level of knowledge)
Usually, this, at the end of an URL, means: jump to the position in page to display the tag whose id follows the hash tag.
Now, I often saw it used by JavaScript code which extracts the information from the hash tag and use it.
So, I suppose here (I don’t know how this add-on works) that we are in a similar case.
If you boldly remove this hash tag, you change the path to your application and might have issues.

I also saw Web applications getting rid of this tag by parsing the URL, using the server’s capability to manipulate URLs (eg. mod_rewrite on Apache) to generate a proper URL internally. Perhaps you can use a similar trick. It is often called SEO-friendly URLs (because Google and similar prefer full URLs to those with hash tags).

I’m not sure on the effect of removing the hash, but my guess is that it’d be ok as I’m not using it as an anchor point on a page.

I’m trying to get it to work with Spring Security, but SS seems to ignore the hash and anything afterwards.

<http use-expressions="true">
    	 <intercept-url pattern="/" access="permitAll" />
    	 <intercept-url pattern="/#rdspage" access="isAuthenticated()" />
    	 <intercept-url pattern="/**" access="denyAll" />
    	 <form-login />
</http>

So all my urls are treated at ‘/’, so the first rule is matched. :wacko:

Stuart.

Because Ajax applications can not modify the URL on the fly without reloading the page, the URI fragment (# part) is used for keeping an URL for navigating to an application state, even though the original use of URI fragments was to refer to anchor points within a page. Use of the URI fragment is important for Navigator7 and can’t be replaced with URL paths.

Your question seems to be really about the use of Spring Security for authentication with Vaadin URI fragment handling. It looks like the same issue was discussed
here
, but I’m not sure if there is a clear solution.

I hope it helps you forward and if you get it working, please make post about it here. As others seem to have experienced the issue as well, it would be good to find a clear answer.

Ok, I’ve not looked into getting spring security to handle the # fragments of the url.
I did, however do this…

 @Override
    public void intercept(PageInvocation pageInvocation) {
    	Class c = pageInvocation.getPageClass();
    	if (c.isAnnotationPresent(HaloAuthority.class)) {            		
    		String ROLE = ((HaloAuthority)c.getAnnotation(HaloAuthority.class)).authority();
    		SimpleGrantedAuthority authority = new SimpleGrantedAuthority(ROLE);
    		if (!CSApplication.getInstance().getUserAuthorities().contains(authority)) {
    			CSApplication.getInstance().navigateTo(AccessDenied.class, "");
    		}
    	}
    		
        pageInvocation.invoke();

        // After invoke, the interceptor chain has been called and the page has been placed.
        if (pageInvocation.isPagePlaced()  // Maybe another interceptor did interrupt the chain. We would not notify if the page had not been actually placed.
                && pageChangeListenerList.size() > 0) {
            // After invoke, the interceptor chain has been called and the page has been placed.
            Component page = pageInvocation.getPageInstance();
            NavigationEvent event = new NavigationEvent(pageInvocation.getNavigator(),
                    WebApplication.getCurrent().getUriAnalyzer(),
                    page.getClass(), pageInvocation.getParams());
            for (PageChangeListener pCL : pageChangeListenerList) {
                pCL.pageChanged(event);
            }
        }
    }

I added an override of the intercept method to a PageChangeListenerInterceptor which checks if your sping security authorities contains the authority described by a page annotaion.
i.e. in my case:


@HaloAuthority(authority="ROLE_ADMIN")
public class UserManager extends CustomComponent {

I used custom annotions, but you could easily use the spring one.


import org.springframework.security.access.annotation.Secured;
@Secured("ROLE_ADMIN")
public class UserManager extends CustomComponent {

If you don’t have the required authority, you get shown the access denied page, courtesy of:

CSApplication.getInstance().navigateTo(AccessDenied.class, "");

(Which is a shortcut to getCurrentNavigableAppLevelWindow().getNavigator().navigateTo() etc…)

I intend to do something similar with a ParamChangeListener.

I make sure the /UIDL/** url is secured with

<intercept-url pattern="/UIDL/**" access="isAuthenticated()" />

Stuart.