You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Łukasz Budnik <lu...@gmail.com> on 2008/03/12 01:53:46 UTC

serious security BUG in MyFaces 1.2.2

Hi All!

I had some trouble with Tomahawk's visibleOnUserRole.
Also, I've tried the securityContext from Tomahawk Sandbox, but it
didn't work either.

I've written simple tests, in every case I use following array of roles:

String[] roles = new String[] { "viewer", "executor", "creator", "admin" };

inside TestFilter.doFilter I have:

for (String role : roles) {
	logger.debug("Is user in '" + role + "' role? ==> "
	+ ((HttpServletRequest) request).isUserInRole(role));
}

inside TestPhaseListener.afterPhase/beforePhase:

for (String role : roles) {
	logger.debug("**after/before** phase Is user in '" + role + "' role? ==> "
	+ phaseEvent.getFacesContext().getExternalContext().isUserInRole(role));
}

and finally inside TestBackingBean I have two loops:

for (String role : roles) {
	logger.debug("Is user in '" + role + "' role? ==> "
	+ FacesContext.getCurrentInstance().getExternalContext().isUserInRole(role));
}
for (String role : roles) {
	logger.debug("Is user in '" + role + "' role? ==> "
	+ ( (HttpServletRequest)
FacesContext.getCurrentInstance().getExternalContext().getRequest()).isUserInRole(role));
}

after successful signing in, I browse a random page, and here's what I
see in my log:

first control flow goes to the filter:

01:27:28,000 DEBUG [TestFilter] Is user in 'viewer' role? ==> true
01:27:28,000 DEBUG [TestFilter] Is user in 'executor' role? ==> true
01:27:28,000 DEBUG [TestFilter] Is user in 'creator' role? ==> true
01:27:28,000 DEBUG [TestFilter] Is user in 'admin' role? ==> true

as expected ;)

now, MyFaces beforePhase:

01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in
'viewer' role? ==> true
01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in
'executor' role? ==> true
01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in
'creator' role? ==> true
01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in 'admin'
role? ==> true

perfect!

and afterPhase:

01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in 'viewer'
role? ==> true
01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in
'executor' role? ==> true
01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in
'creator' role? ==> true
01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in 'admin'
role? ==> true

couldn't be better!


BUT ;(

inside the backing bean:

01:27:28,171 DEBUG [TestBackingBean] Is user in 'viewer' role? ==> false
01:27:28,171 DEBUG [TestBackingBean] Is user in 'executor' role? ==> false
01:27:28,171 DEBUG [TestBackingBean] Is user in 'creator' role? ==> false
01:27:28,171 DEBUG [TestBackingBean] Is user in 'admin' role? ==> false
01:27:28,187 DEBUG [TestBackingBean] Is user in 'viewer' role? ==> false
01:27:28,187 DEBUG [TestBackingBean] Is user in 'executor' role? ==> false
01:27:28,187 DEBUG [TestBackingBean] Is user in 'creator' role? ==> false
01:27:28,187 DEBUG [TestBackingBean] Is user in 'admin' role? ==> false

disaster!

security in MyFaces 1.2.2 does not work at all (except for phase
listeners, which is useless for me anyway).

any idea how to fix it?

best regards
Łukasz

Re: serious security BUG in MyFaces 1.2.2

Posted by Łukasz Budnik <lu...@gmail.com>.
Hi All!

I've written very simple work around for this. I use session backing
bean: AuthorizationController to store user and his/hers roles and
AuthorizationPhaseListener to retrieve the roles and users from the
original request.

This is how it looks like:

public class AuthorizationPhaseListener implements PhaseListener {

	private static final long serialVersionUID = 2078973126942159155L;

	protected final static Logger logger = Logger
			.getLogger(AuthorizationPhaseListener.class);

	@SuppressWarnings("deprecation")
	public void afterPhase(PhaseEvent phaseEvent) {
		FacesContext facesContext = phaseEvent.getFacesContext();

		// check if user has been authorized by JAAS, if not return
		if (facesContext.getExternalContext().getRemoteUser() == null) {
			return;
		}

		// there is a remote user set by JAAS

		// MyFaces 1.2.2 security bug, cannot retrieve managed bean because it
		// erases all roles, copy them before ;)
		Map<String, Boolean> rolesMap = new HashMap<String, Boolean>(4);
		String[] roles = new String[] { "viewer", "executor", "creator",
				"admin" };

		for (String role : roles) {
			logger.debug("Is user in '"
					+ role
					+ "' role? ==> "
					+ phaseEvent.getFacesContext().getExternalContext()
							.isUserInRole(role));
			rolesMap.put(role, phaseEvent.getFacesContext()
					.getExternalContext().isUserInRole(role));
		}

		AuthorizationController authorizationController =
(AuthorizationController) facesContext
				.getApplication().createValueBinding(
						"#{AuthorizationController}").getValue(facesContext);

		logger.debug("Remote user is ==> "
				+ facesContext.getExternalContext().getRemoteUser());
		logger.debug("Authorized user is ==> "
				+ authorizationController.getUser());

		// if user is already authorized, return
		if (authorizationController.getUser() != null
				&& facesContext.getExternalContext().getRemoteUser() != null) {
			return;
		}

		// if not, proceed

		// load user
		authorizationController.loadUser(facesContext.getExternalContext()
				.getRemoteUser());

		// and set proper roles
		for (String role : rolesMap.keySet()) {
			if (rolesMap.get(role)) {
				authorizationController.setRole(role);
			}
		}

	}

	public void beforePhase(PhaseEvent phaseEvent) {
	}

	public PhaseId getPhaseId() {
		return PhaseId.RESTORE_VIEW;
	}

}


now, inside any view I can now user for example
rendered="#{AuthorizationController.admin}"

best regards
Łukasz

On 12/03/2008, Łukasz Budnik <lu...@gmail.com> wrote:
> Hi All!
>
>  I had some trouble with Tomahawk's visibleOnUserRole.
>  Also, I've tried the securityContext from Tomahawk Sandbox, but it
>  didn't work either.
>
>  I've written simple tests, in every case I use following array of roles:
>
>  String[] roles = new String[] { "viewer", "executor", "creator", "admin" };
>
>  inside TestFilter.doFilter I have:
>
>  for (String role : roles) {
>         logger.debug("Is user in '" + role + "' role? ==> "
>         + ((HttpServletRequest) request).isUserInRole(role));
>  }
>
>  inside TestPhaseListener.afterPhase/beforePhase:
>
>  for (String role : roles) {
>         logger.debug("**after/before** phase Is user in '" + role + "' role? ==> "
>         + phaseEvent.getFacesContext().getExternalContext().isUserInRole(role));
>  }
>
>  and finally inside TestBackingBean I have two loops:
>
>  for (String role : roles) {
>         logger.debug("Is user in '" + role + "' role? ==> "
>         + FacesContext.getCurrentInstance().getExternalContext().isUserInRole(role));
>  }
>  for (String role : roles) {
>         logger.debug("Is user in '" + role + "' role? ==> "
>         + ( (HttpServletRequest)
>  FacesContext.getCurrentInstance().getExternalContext().getRequest()).isUserInRole(role));
>  }
>
>  after successful signing in, I browse a random page, and here's what I
>  see in my log:
>
>  first control flow goes to the filter:
>
>  01:27:28,000 DEBUG [TestFilter] Is user in 'viewer' role? ==> true
>  01:27:28,000 DEBUG [TestFilter] Is user in 'executor' role? ==> true
>  01:27:28,000 DEBUG [TestFilter] Is user in 'creator' role? ==> true
>  01:27:28,000 DEBUG [TestFilter] Is user in 'admin' role? ==> true
>
>  as expected ;)
>
>  now, MyFaces beforePhase:
>
>  01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in
>  'viewer' role? ==> true
>  01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in
>  'executor' role? ==> true
>  01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in
>  'creator' role? ==> true
>  01:27:28,015 DEBUG [TestPhaseListener] before phase Is user in 'admin'
>  role? ==> true
>
>  perfect!
>
>  and afterPhase:
>
>  01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in 'viewer'
>  role? ==> true
>  01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in
>  'executor' role? ==> true
>  01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in
>  'creator' role? ==> true
>  01:27:28,015 DEBUG [TestPhaseListener] after phase Is user in 'admin'
>  role? ==> true
>
>  couldn't be better!
>
>
>  BUT ;(
>
>  inside the backing bean:
>
>  01:27:28,171 DEBUG [TestBackingBean] Is user in 'viewer' role? ==> false
>  01:27:28,171 DEBUG [TestBackingBean] Is user in 'executor' role? ==> false
>  01:27:28,171 DEBUG [TestBackingBean] Is user in 'creator' role? ==> false
>  01:27:28,171 DEBUG [TestBackingBean] Is user in 'admin' role? ==> false
>  01:27:28,187 DEBUG [TestBackingBean] Is user in 'viewer' role? ==> false
>  01:27:28,187 DEBUG [TestBackingBean] Is user in 'executor' role? ==> false
>  01:27:28,187 DEBUG [TestBackingBean] Is user in 'creator' role? ==> false
>  01:27:28,187 DEBUG [TestBackingBean] Is user in 'admin' role? ==> false
>
>  disaster!
>
>  security in MyFaces 1.2.2 does not work at all (except for phase
>  listeners, which is useless for me anyway).
>
>  any idea how to fix it?
>
>  best regards
>
> Łukasz
>