Here is a CAS client for Vaadin 7 you can use with any other dependency rather than the CAS client library. You don't need any filter with Apache Shiro as it is suggested on the official Vaadin website. To use it, just import the class into your project. Then, your UI class must extend it. Don't forget to adapt the source code to your context. You have to set your CAS server URL and eventually change the attributes you want to extract from the CAS response. Once the user is authenticated, a VaadinUser class instance is created. Just call VaadinUser.getCurrent() static method from everywhere to get it.
The class to import :
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Saml11TicketValidator;
import org.jasig.cas.client.validation.TicketValidationException;
import org.springframework.beans.factory.annotation.Value;
import com.essec.cas.selfservice.util.spring.SpringDependencyInjector;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.UI;
/**
* Basic CAS authenticated UI for Vaadin 7.1.0. <br/>
* Just import this class into your project <br/>
* . All cassified UI have to extend this class<br/>
* <br/>
* Once the user is logged in, you can call VaadinUser.getCurrent() <br/>
* from anywhere in your code to get the authenticated user. <br/>
*
*
* @author Alexandre de Pellegrin - ESSEC Business School
*
*/
public class CasAuthenticatedUI extends UI {
/** Set your CAS server URL here */
private String SSO_CAS_BASE_URL = https://myserver/cas
@Override
protected void init(VaadinRequest request) {
try {
if (isTicketToValidate(request)) {
boolean isValidated = validateTicket(request);
if (isValidated) {
reloadPage();
return;
}
}
if (!isAuthenticated()) {
redirectToLoginPage(request);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* This method can be called in this init() methods from the inherited class
* to avoid loading page content when it is not necessary and to avoid
* screen flickering. <br/>
* Example : <br/>
* protected void init(VaadinRequest request) {<br/>
* super.init(request);<br/>
* if (!super.isReadyToDisplayContent()) {<br/>
* return;<br/>
* }<br/>
* setContent(getContentLayout());<br/>
* }<br/>
* <br/>
*
* @return true if authentication step is finished
*/
protected boolean isReadyToDisplayContent() {
if (!isAuthenticated()) {
return false;
}
if (getPagePublicURL().contains("restartApplication")) {
return false;
}
return true;
}
/**
* @return true if the user has already been authenticated on the CAS server
*/
private boolean isAuthenticated() {
VaadinUser authenticatedUser = getSession().getAttribute(VaadinUser.class);
if (authenticatedUser != null) {
return true;
}
return false;
}
/**
* Redirects to the CAS login page
*/
private void redirectToLoginPage(VaadinRequest request) throws IOException {
String pageURL = getPagePublicURL();
String redirectURL = getSSOBaseURL() + "/login?service=" + pageURL;
getPage().setLocation(redirectURL);
}
/**
* Reloads page without the service ticket to avoid multiple submit with the
* same ticket
*/
private void reloadPage() throws IOException {
String pageURL = getPagePublicURL();
pageURL = removeParamFromURL(pageURL, "restartApplication");
getPage().setLocation(pageURL);
}
/**
* @return CAS url
*/
private String getSSOBaseURL() {
return SSO_CAS_BASE_URL;
}
/**
* @return true if there's a CAS service ticket in the current request
*/
private boolean isTicketToValidate(VaadinRequest request) {
String ticketValue = getTicket(request);
if (ticketValue != null) {
return true;
}
return false;
}
/**
* @return the current CAS service ticket
*/
private String getTicket(VaadinRequest request) {
return request.getParameter("ticket");
}
/**
* Validates the CAS service ticket on the CAS server
*/
private boolean validateTicket(VaadinRequest request) {
String ticket = getTicket(request);
if (ticket == null) {
return false;
}
String ticketValue = ticket.toString();
String pageURL = getPagePublicURL();
VaadinSession session = getSession();
try {
// You should customize this part depending on your CAS server
// configuration
Saml11TicketValidator ticketValidator = new Saml11TicketValidator(getSSOBaseURL());
ticketValidator.setTolerance(300000);
Assertion assertion = ticketValidator.validate(ticketValue, pageURL);
AttributePrincipal principal = assertion.getPrincipal();
String user = principal.getName();
Map<?, ?> attributes = principal.getAttributes();
List<String> roles = (List<String>) attributes.get("roles");
VaadinUser authenticatedUser = new VaadinUser();
authenticatedUser.setName(user);
if (roles != null) {
authenticatedUser.setRoles(roles);
}
// Push authentication user into Vaadin application
session.setAttribute(VaadinUser.class, authenticatedUser);
return true;
} catch (TicketValidationException e) {
session.close();
}
return false;
}
/**
* @return the url of this page as seen by the browser
*/
private String getPagePublicURL() {
URI location = getPage().getLocation();
String pageURL = location.toString();
pageURL = removeParamFromURL(pageURL, "ticket");
return pageURL;
}
/**
* @return the given url without the specified parameter
*/
private String removeParamFromURL(String url, String paramName) {
url = url.replaceFirst("([?&]{1})(" + paramName + "=[^&]*|" + paramName + ")(&?)", "$1$3");
url = url.replaceFirst("\\?&", "?");
url = url.replaceFirst("\\?$|&$", "");
return url;
}
/**
* Represents a user
*
* @author Alexandre de Pellegrin
*
*/
public static class VaadinUser {
private String name;
private List<String> roles = new ArrayList<String>();
public String getName() {
return name;
}
public void setName(String principal) {
this.name = principal;
}
public List<String> getRoles() {
return roles;
}
public void setRoles(List<String> roles) {
this.roles = roles;
}
public boolean isUserInRole(String role) {
for (String aRole : roles) {
if (aRole.contains(role)) {
return true;
}
}
return false;
}
public static VaadinUser getCurrent() {
UI currentUI = UI.getCurrent();
if (currentUI == null) {
return null;
}
VaadinSession vaadinSession = currentUI.getSession();
if (vaadinSession == null) {
return null;
}
return vaadinSession.getAttribute(VaadinUser.class);
}
}
}
How to use it : a small example
public class MyApplicationUI extends CasAuthenticatedUI {
private CustomLayout contentLayout;
private Panel mainPanel;
@Override
protected void init(VaadinRequest request) {
super.init(request);
if (!super.isReadyToDisplayContent()) {
return;
}
setContent(...);
}
...
public class MyPanel extends Panel {
public MyPanel() {
super();
setContent(new Label(VaadinUser.getCurrent().getName()));
}