Configuring Basic or Digest Authentication for Tomcat-based WebDAV Server
Basic/Digest Authentication
Important! Microsoft Office on Windows and Mac OS X as well as Windows Shell (Web Folders / mini-redirector), requires secure SSL connection when used with Basic authentication. Microsoft Office will fail to open a document via insecure connection with Basic authentication. For a workaround please see the following articles. In case of MS Office Windows: You cannot open Office file types directly from a server that only supports Basic Authentication over a non-SSL connection with Office applications. In case of MS Office on OS X: You cannot open Office for Mac files directly from a server that supports only Basic authentication over a non-SSL connection.
To configure Basic or Digest authentication using Tomcat preconfigured users/roles:
- Configure roles that will have access to webdav repository in /WEB-INF/web.xml file using <security-constraint> element (under <web-app> element):
<web-app ... > ... <security-constraint> <!-- web resources that are protected --> <web-resource-collection> <web-resource-name>All Resources</web-resource-name> <url-pattern>/*</url-pattern> <!-- All methods but OPTIONS must be authenticated. OPTIONS must work without authentication for cross domain in Firefox to work --> <http-method>GETLIB</http-method> <http-method>COPY</http-method> <http-method>MOVE</http-method> <http-method>DELETE</http-method> <http-method>PROPFIND</http-method> <http-method>GET</http-method> <http-method>HEAD</http-method> <http-method>PUT</http-method> <http-method>MKCOL</http-method> <http-method>PROPPATCH</http-method> <http-method>LOCK</http-method> <http-method>UNLOCK</http-method> <http-method>VERSION-CONTROL</http-method> <http-method>CHECKIN</http-method> <http-method>CHECKOUT</http-method> <http-method>UNCHECKOUT</http-method> <http-method>REPORT</http-method> <http-method>UPDATE</http-method> <http-method>CANCELUPLOAD</http-method> </web-resource-collection> <auth-constraint> <!-- role-name indicates roles that are allowed to access the web resource specified above --> <role-name>administrators</role-name> <role-name>role1</role-name> </auth-constraint> </security-constraint> ... </web-app>
- Configure roles:
<web-app ... > ... <security-role> <role-name>administrators</role-name> <role-name>role1</role-name> </security-role> ... </web-app>
- Configure authentication:
- For Basic authentication add following element after <security-constraint> element:
<web-app ... > ... <login-config> <auth-method>BASIC</auth-method> <realm-name>Basic Authentication</realm-name> </login-config> ... </web-app>
- For Digest authentication add following element:
<web-app ... > ... <login-config> <auth-method>DIGEST</auth-method> <realm-name>Digest Authentication</realm-name> </login-config> ... </web-app>
- For Basic authentication add following element after <security-constraint> element:
- Configure users, their names, passwords and roles they belong to in <TOMCAT_HOME>/conf/tomcat-users.xml:
<tomcat-users> <role rolename="manager"/> <role rolename="admin"/> <role rolename="administrators"/> <user username="admin" password="admin" roles="admin,manager"/> <user username="sergey" password="sergey" roles="administrators"/> </tomcat-users>
In your code, you will be able to access logged in user using request.isUserInRole method:
public List<HierarchyItemImpl> getChildren() throws ServerException { if (this.getEngine().getRequest().isUserInRole("administrators")){ // list items } else{ throw new ServerException(WebDavStatus.ACCESS_DENIED); } }
Authentication Against Custom Users Storage with Tomcat
To authenticate against your credential store using Basic or Digest authentication you need to:
- Implement Tomcat custom realm:
import java.security.Principal; import org.apache.catalina.realm.RealmBase; public class CustomRealm extends RealmBase { public boolean hasRole(Principal principal, String role) { //determine if principal is in role } protected String getPassword(String username) { // return password of user with name = 'username' } protected Principal getPrincipal(String username) { return new CustomPrincipal(username); } class CustomPrincipal implements Principal { private final String name; public CustomPrincipal(String name) { this.name = name; } public String getName() { return name; } public String toString() { return getName(); } } }
- Configure Tomcat to use Custom Realm in <TOMCAT_HOME>/conf/server.xml
<Server ...> ... <!-- Because this Realm is here, an instance will be shared globally <Realm className="org.apache.catalina.realm.MemoryRealm" /> --> <Realm className="CustomRealm"/> ... </Server>