diff --git a/uw-spring-security-web/pom.xml b/uw-spring-security-web/pom.xml
index e67360b09ca9938331dc408e4d2cf99346be9018..0e764a9b024cd4102ad8d06cd0a1b79a8f54cb6a 100644
--- a/uw-spring-security-web/pom.xml
+++ b/uw-spring-security-web/pom.xml
@@ -20,6 +20,11 @@
 			<artifactId>junit</artifactId>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-core</artifactId>
+			<scope>test</scope>
+		</dependency>
 		<dependency>
 			<groupId>org.slf4j</groupId>
 			<artifactId>slf4j-log4j12</artifactId>
diff --git a/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/PviAttributeBindingFilter.java b/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/PviAttributeBindingFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..3054c2dd768823d035df623ee8f21eecb8072614
--- /dev/null
+++ b/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/PviAttributeBindingFilter.java
@@ -0,0 +1,54 @@
+package edu.wisc.uwss.web;
+
+import edu.wisc.uwss.UWUserDetails;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.filter.GenericFilterBean;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Filter to a UW user's PVI to a request. This sets an attribute named "wiscedupvi" to the value
+ * of the currently authenticated user.
+ */
+public class PviAttributeBindingFilter extends GenericFilterBean {
+
+    private static final Logger logger = LoggerFactory.getLogger(PviAttributeBindingFilter.class);
+
+    /**
+     * Add an attribute to the request with the currently authenticated user's PVI.
+     *
+     * @param servletRequest the request
+     * @param servletResponse the response
+     * @param filterChain the filter chain
+     * @throws IOException
+     * @throws ServletException
+     */
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletRequest req = (HttpServletRequest)servletRequest;
+        HttpServletResponse res = (HttpServletResponse)servletResponse;
+
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+        if (auth != null) {
+            Object principal = auth.getPrincipal();
+            if (principal instanceof UWUserDetails) {
+                UWUserDetails userDetails = (UWUserDetails)principal;
+                logger.debug("adding PVI attribute with value {} to request", userDetails.getPvi());
+                req.setAttribute("wiscedupvi", userDetails.getPvi());
+            }
+        }
+
+        filterChain.doFilter(req, res);
+    }
+
+}
diff --git a/uw-spring-security-web/src/test/java/edu/wisc/uwss/web/PviAttributeBindingFilterTest.java b/uw-spring-security-web/src/test/java/edu/wisc/uwss/web/PviAttributeBindingFilterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff2b33313be877a9b6870de8375bd79b9a6fab8e
--- /dev/null
+++ b/uw-spring-security-web/src/test/java/edu/wisc/uwss/web/PviAttributeBindingFilterTest.java
@@ -0,0 +1,56 @@
+package edu.wisc.uwss.web;
+
+import edu.wisc.uwss.UWUserDetails;
+import edu.wisc.uwss.UWUserDetailsImpl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link PviAttributeBindingFilter}
+ *
+ * @author apsummers
+ */
+public class PviAttributeBindingFilterTest {
+
+    private PviAttributeBindingFilter filter;
+    private MockHttpServletRequest req;
+    private MockHttpServletResponse res;
+    private MockFilterChain filterChain;
+
+    @Before
+    public void setUp() {
+        filter = new PviAttributeBindingFilter();
+        req = new MockHttpServletRequest();
+        res = new MockHttpServletResponse();
+        filterChain = new MockFilterChain();
+    }
+
+    @Test
+    public void testDoFilter() throws ServletException, IOException {
+        // Create a UWUserDetails to represent the requesting user
+        UWUserDetails principal = new UWUserDetailsImpl("UW000A000", "admin", "password", "Amy Admin", "amy.admin@wisc.edu");
+        PreAuthenticatedAuthenticationToken preauthToken = new PreAuthenticatedAuthenticationToken(principal, null);
+
+        // Setup security context
+        SecurityContext securityContext = Mockito.mock(SecurityContext.class);
+        Mockito.when(securityContext.getAuthentication()).thenReturn(preauthToken);
+        SecurityContextHolder.setContext(securityContext);
+        
+        filter.doFilter(req, res, filterChain);
+        assertEquals("UW000A000", req.getAttribute("wiscedupvi"));
+    }
+
+}