Spring Security - Pre-Authentication
Using spring security is a scenario where we need to check for users pre-authentication while accessing the application. For example valid user logged-in to ABC application, and inside ABC application there are XYZ services running which require user authentication, but users who access ABC application should not require to authenticate again by XYZ services when they access through ABC application, just need to pre-authenticate by earlier login details.
Here Spring Security Pre-Authentication plays the role for us. For more details and methods and classes please refer to Spring docs link.
Directly lets see simple example to authenticate user based on request param. Here all services and pages are filtered through security chain and only valid users can access like "admin", "dba" and "user".
pom.xml
spring-mvc-servlet.xml
web.xml
access-denied.jsp
UrlParametersAuthenticationFilter.java
AuthenticationEntryPointDenied.java
UserDetailsServiceImpl.java
Employee.java
Employees.java
DemoController.java
OUTPUT:
URL : http://localhost:8080/springsecuritybyurl/employees?param1=bill
URL : http://localhost:8080/springsecuritybyurl/employees?param1=admin
Download complete sample project from below link.
Spring Security - Pre-Authentication.
Here Spring Security Pre-Authentication plays the role for us. For more details and methods and classes please refer to Spring docs link.
Directly lets see simple example to authenticate user based on request param. Here all services and pages are filtered through security chain and only valid users can access like "admin", "dba" and "user".
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.app.mvc</groupId>
<artifactId>springsecuritybyurl</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Spring Security By URL</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>3.0.5.RELEASE</spring.version>
<jackson-mapper-asl.version>1.9.9</jackson-mapper-asl.version>
<jaxb-api.version>2.2.7</jaxb-api.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson-mapper-asl.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>springsecuritybyurl</finalName>
</build>
</project>
spring-mvc-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<!-- Annotation are configuring the application -->
<mvc:annotation-driven />
<!-- Scan this package for all config annotations -->
<context:component-scan base-package="com.app.controller" />
<security:http create-session="never" use-expressions="true"
auto-config="false" entry-point-ref="preAuthenticatedProcessingFilterEntryPoint">
<security:intercept-url pattern="/jsp/access-denied.jsp"
access="permitAll()" />
<security:intercept-url pattern="/accessdenied.do"
access="permitAll()" />
<security:intercept-url pattern="/**"
access="hasRole('ROLE_USER')" />
<security:custom-filter position="PRE_AUTH_FILTER"
ref="preAuthFilter" />
<security:session-management
session-fixation-protection="none" />
</security:http>
<bean id="preAuthFilter" class="com.app.filter.UrlParametersAuthenticationFilter">
<property name="authenticationManager" ref="appControlAuthenticationManager" />
</bean>
<bean id="preAuthenticationProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="UserDetailsServiceImpl" />
</bean>
<security:authentication-manager alias="appControlAuthenticationManager">
<security:authentication-provider
ref="preAuthenticationProvider" />
</security:authentication-manager>
<bean id="UserDetailsServiceImpl" class="com.app.security.UserDetailsServiceImpl" />
<bean id="preAuthenticatedProcessingFilterEntryPoint" class="com.app.security.AuthenticationEntryPointDenied" />
<!-- <bean id="customUserDetailsService" class="com.app.security.CustomUserDetailsService"></bean>
<bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"></bean> -->
</beans>
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Spring Security By URL</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-mvc-servlet.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>accessTest</servlet-name>
<jsp-file>/WEB-INF/jsp/access-denied.jsp</jsp-file>
</servlet>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>accessTest</servlet-name>
<url-pattern>/accessdenied.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
access-denied.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>
<html>
<head>
<title>Invalid user</title>
</head>
<body>
<h1>Oops, Access denied....</h1>
</body>
</html>
UrlParametersAuthenticationFilter.java
package com.app.filter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
public class UrlParametersAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
//Checking for no. of URL params
if (request.getParameterMap().size() == 1) {
return true;
}
return false;
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
String[] credentials = new String[1];
//Getting authentication credentials
credentials[0] = request.getParameter("param1");
return credentials;
}
}
AuthenticationEntryPointDenied.java
package com.app.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
public class AuthenticationEntryPointDenied implements AuthenticationEntryPoint {
public void commence(HttpServletRequest request,
HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
// Redirecting service to access denied page for invalid users
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, "/accessdenied.do");
}
}
UserDetailsServiceImpl.java
package com.app.security;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class UserDetailsServiceImpl implements AuthenticationUserDetailsService {
public UserDetails loadUserDetails(Authentication token)
throws UsernameNotFoundException {
UserDetails userDetails = null;
String[] credentials = (String[]) token.getCredentials();
boolean principal = Boolean.valueOf(token.getPrincipal().toString());
if (credentials != null && principal == true) {
String name = credentials[0];
// Setting user Authorities
if ("admin".equalsIgnoreCase(name)) {
userDetails = getAdminUser(name);
} else if ("dba".equalsIgnoreCase(name)) {
userDetails = getDBAUser(name);
} else if ("user".equalsIgnoreCase(name)) {
userDetails = getUserUser(name);
}
}
if (userDetails == null) {
throw new UsernameNotFoundException("Invalid user - "
+ credentials[0]);
}
return userDetails;
}
private UserDetails getAdminUser(String username) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_DBA"));
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
return new User(username, "notused", true, true, true, true,
grantedAuthorities);
}
private UserDetails getDBAUser(String username) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_DBA"));
return new User(username, "notused", true, true, true, true,
grantedAuthorities);
}
private UserDetails getUserUser(String username) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
return new User(username, "notused", true, true, true, true,
grantedAuthorities);
}
}
Employee.java
package com.app.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="employee")
@XmlAccessorType(XmlAccessType.NONE)
public class Employee {
@XmlElement(name="firstName")
private String firstName;
@XmlElement(name="lastName")
private String lastName;
@XmlElement(name="role")
private String role;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Employees.java
package com.app.model;
import java.util.Collection;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="employees")
@XmlAccessorType(XmlAccessType.NONE)
public class Employees
{
@XmlElement(name="employee")
private Collection<Employee> employees;
public Collection<Employee> getUsers() {
return employees;
}
public void setUsers(Collection<Employee> employees) {
this.employees = employees;
}
}
DemoController.java
package com.app.controller;
import java.util.ArrayList;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.app.model.Employee;
import com.app.model.Employees;
@Controller
@RequestMapping("/employees")
public class DemoController
{
@RequestMapping(method = RequestMethod.GET, headers="Accept=application/xml")
public @ResponseBody Employees getEmployees()
{
String userRole = getUserRole();
System.out.println("User Role : "+userRole);
Employee emp1 = new Employee();
Employee emp2 = new Employee();
if(userRole.equals("admin")){
emp1.setFirstName("Bala");
emp1.setLastName("Raj");
emp1.setRole("ADMIN");
emp2.setFirstName("Tim");
emp2.setLastName("Rock");
emp2.setRole("ADMIN");
}else if(userRole.equals("dba")){
emp1.setFirstName("Steve");
emp1.setLastName("Jose");
emp1.setRole("DBA");
emp2.setFirstName("Bill");
emp2.setLastName("Fish");
emp2.setRole("DBA");
}else if(userRole.equals("user")){
emp1.setFirstName("Joy");
emp1.setLastName("Tiger");
emp1.setRole("USER");
emp2.setFirstName("Wood");
emp2.setLastName("Rich");
emp2.setRole("USER");
}
Employees emps = new Employees();
emps.setUsers(new ArrayList<Employee>());
emps.getUsers().add(emp1);
emps.getUsers().add(emp2);
return emps;
}
private String getUserRole(){
String userRole = "";
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
for (GrantedAuthority auth : authentication.getAuthorities()) {
if ("ROLE_ADMIN".equals(auth.getAuthority())){
userRole = "admin";
break;
}
if ("ROLE_DBA".equals(auth.getAuthority())){
userRole = "dba";
break;
}
if ("ROLE_USER".equals(auth.getAuthority())){
userRole = "user";
break;
}
}
return userRole;
}
}
OUTPUT:
URL : http://localhost:8080/springsecuritybyurl/employees?param1=bill
URL : http://localhost:8080/springsecuritybyurl/employees?param1=admin
Download complete sample project from below link.
Spring Security - Pre-Authentication.