Secured Navigator
Example code is available on github.com/vaadin-on-grails/spring-security-basics.
In this article we will show way how to create Vaadin application with secured views, where a view will be viewable by certain role.
Step 1
In ViewSecurity
class we will store the mapping of a view to user roles. The class will be also responsible to verify whether a view is accesible by a user.
package app.security
import com.vaadin.navigator.View
import org.springframework.security.authentication.InternalAuthenticationServiceException
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
class ViewSecurity {
private static Map<Class<? extends View>, List<String>> views = [:]
static add(Class<? extends View> view, List<String> roles) {
views.put(view, roles)
}
static boolean isViewAccessible(View view) {
List<String> roles = views.get(view.class)
if (!roles) {
// if roles is null, the access is public (not secured)
return true
}
Authentication authentication = SecurityContextHolder.context.authentication
if (!authentication) {
throw new InternalAuthenticationServiceException('No authentication found in the context.')
}
List<GrantedAuthority> authorities = authentication.authorities
for (String role : roles) {
boolean isRoleAssigned = role in authorities*.authority
if (isRoleAssigned) {
return true
}
}
return false
}
}
Step 2
We need to hook at event when a view changes, so we can verify whether a user is able to access a view.
package app.security
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
class SecuredViewChangeListener implements ViewChangeListener {
@Override
boolean beforeViewChange(ViewChangeListener.ViewChangeEvent event) {
View view = event.newView
boolean isViewAccessible = ViewSecurity.isViewAccessible(view)
return isViewAccessible
}
@Override
void afterViewChange(ViewChangeListener.ViewChangeEvent event) {
}
}
Step 3
Now we will create two views where one will be accesible only by "ADMIN" role.
package app.view.secured
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
class UserDataView extends VerticalLayout implements View {
static final String VIEW_NAME = "secured"
@Override
void enter(ViewChangeListener.ViewChangeEvent event) {
setMargin(true)
addComponent(new Label("Secured content, only after login!"))
}
}
And the second view, LoginView
, that will public to everyone.
package app.view.login
import app.security.Auth
import app.view.secured.UserDataView
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Button
import com.vaadin.ui.TextField
import com.vaadin.ui.VerticalLayout
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import static com.vaadin.ui.UI.getCurrent
class LoginView extends VerticalLayout implements View {
static final String VIEW_NAME = "login"
@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
TextField txnUsername = new TextField("Username")
TextField txnPassword = new TextField("Password")
Button btnLogin = new Button("Login")
addComponent(txnUsername)
addComponent(txnPassword)
addComponent(btnLogin)
btnLogin.addClickListener(new Button.ClickListener() {
@Override
void buttonClick(Button.ClickEvent clickEvent) {
String username = txnUsername.value
String password = txnPassword.value
try {
Authentication auth = Auth.login(username, password)
List<GrantedAuthority> authorities = auth.authorities
if ('ADMIN' in authorities*.authority) {
current.navigator.navigateTo(UserDataView.VIEW_NAME)
} else {
current.navigator.navigateTo(LoginView.VIEW_NAME)
}
} catch (BadCredentialsException e) {
// TODO: handle error flow
current.navigator.navigateTo(LoginView.VIEW_NAME)
}
}
})
}
}
Step 4
Now we will create UI
class that will initialize Navigator
and ViewSecurity
.
package app
import app.security.SecuredViewChangeListener
import app.security.ViewSecurity
import app.view.login.LoginView
import app.view.secured.UserDataView
import com.vaadin.annotations.PreserveOnRefresh
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
@PreserveOnRefresh
class MyUI extends UI {
@Override
protected void init(VaadinRequest r) {
VerticalLayout layout = new VerticalLayout()
layout.setMargin(true)
Navigator navigator = new Navigator(this, this)
SecuredViewChangeListener securedViewListener = new SecuredViewChangeListener()
navigator.addViewChangeListener(securedViewListener)
navigator.addView(LoginView.VIEW_NAME, LoginView)
navigator.addView(UserDataView.VIEW_NAME, UserDataView)
ViewSecurity.add(LoginView, null)
ViewSecurity.add(UserDataView, ['ADMIN'])
navigator.navigateTo(LoginView.VIEW_NAME)
setContent(layout)
}
}
Step 5
Run application grails run-app
and fill in username and password.

Click on Login
button and you will be authentificated and redirected to secured view.

Last updated
Was this helpful?