top of page

Spring Security

  • Writer: megha dureja
    megha dureja
  • May 25, 2020
  • 5 min read

Updated: Feb 25, 2021

Spring Security is a framework that enables a programmer to impose security restrictions to Spring-framework–based Web applications through JEE components.




Features

  • Comprehensive and extensible support for both Authentication and Authorization

  • Protection against attacks like session fixation, clickjacking, cross site request forgery, etc

  • Servlet API integration

  • Optional integration with Spring Web MVC


1) Security Concepts:-


1. Spring Security extends the Java standard security concept of an authenticated principal (java.security.Principal).

2. Principal will represent a single user. User <-> Principal


3. Authentication - process of verifying users of an application. This can be done via

a. Credential-based approach :- username/password which is stored in DB or LDAP

b. Two-factor based approach :- username/password and then security Q_A


4. Authorization - process of describing accessibility of secured resources(web pages, portions of pages)


It involves 2 separate aspects

1) map authenticated principal to one or more ROLES(Authorities)

2) authority check to secured resources of the application


A component called the "Access Decision Manager" is responsible for determining whether a principal has the appropriate level of access, based on the match between the authority possessed by the principal and the authority requested by the resource.


2) Configure Spring Security In an application:-


a) An older three step configuration:-


1) Create an XML configuration file, representing all Spring Security components required to cover standard web requests.

<http auto-config="true">
 <intercept-url pattern="/*" access="ROLE_USER"/>
 <form-login login-page="/login.do" />
 </http>
 <authentication-manager alias="authenticationManager">
 <authentication-provider>
 <user-service>
 <user authorities="ROLE_USER" name="guest" password="guest"/>
</user-service>
 </authentication-provider>
 </authentication-manager>

Our declaration of the <user-service> subelement triggered a configuration of the InMemoryDaoImpl implementation of the UserDetailsService which is a default implementation .


OR


Instead of the Spring Security in-memory UserDetailsService, we can use JdbcDaoImpl implementation of UserDetailsService as well.

<authentication-manager alias="authenticationManager">
 <authentication-provider>
 <jdbc-user-service data-source-ref="dataSource"/>
 </authentication-provider>
</authentication-manager>
<bean id="jdbcUserService"
 class="com.packtpub.springsecurity.security.CustomJdbcDaoImpl">
 <property name="dataSource" ref="dataSource"/>
</bean>

2) Configure a reference to this filter by adding the following code to our web.xml deployment descriptor, right after the end of our Spring MVC <servlet-mapping> element:

<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>

The o.s.web.filter.DelegatingFilterProxy is a servlet filter that allowsSpring Security to wrap all application requests (/*) and ensure that they are appropriately secured.


3) Adding Spring Security XML configuration file reference to web.xml


<context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>
 /WEB-INF/xxxx-security.xml
 </param-value>
</context-param>

So, we've implemented a basic layer of security in our application. We've had to hardcode the username, password, and role information of the user in the XML configuration file.


b) A new way of configuring Spring Security

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
				.antMatchers("/").permitAll()
				.anyRequest().authenticated()
				.and()
			.formLogin()
				.loginPage("/login")
				.permitAll()
				.and()
			.logout()
				.permitAll();
	}

	@Bean
	@Override
	public UserDetailsService userDetailsService() {
		UserDetails user =
			 User.withDefaultPasswordEncoder()
				.username("guest")
				.password("guest")
				.roles("ROLE_USER")
				.build();

		return new InMemoryUserDetailsManager(user);
	}
}

Here, we didn't wire AuthenticationProvider to any explicit implementation(DB, LDAP etc), we used an in-memory credential store which is a default implementation. The above method userDetailsService() will by default instantiate an out of the box implementation known as DaoAuthenticationProvider and will also automatically wire this AuthenticationProvider to the configured AuthenticationManager.


Basically, DaoAuthenticationProvider is an AuthenticationProvider that provides a thin wrapper to implement the AuthenticationProvider interface and then delegates to an implementation of the UserDetailsService interface. The UserDetailsService is responsible for returning an implementation of UserDetails.


Now we'll need to replace this with a database-based authentication or LDAP provider. Goto point 4).


3) Spring Security architecture


1. Spring Security takes the filter chain concept and implements its own abstraction. The architecture relies heavily on the use of delegates and servlet filters to provide layers of functionality around the context of a web application request.


2. The automatic configuration attribute in the Spring Security XML configuration file sets up a series of below 10 servlet filters, which are applied in a sequence through the use of a Java EE servlet filter chain (javax.servlet.FilterChain).

o.s.s.web.context.SecurityContextPersistenceFilter
o.s.s.web.authentication.logout.LogoutFilter
o.s.s.web.authentication.UsernamePasswordAuthenticationFilter
o.s.s.web.authentication.ui.DefaultLoginPageGeneratingFilter
o.s.s.web.authentication.www.BasicAuthenticationFilter
o.s.s.web.savedrequest.RequestCacheAwareFilter
o.s.s.web.servletapi.SecurityContextHolderAwareRequestFilter
o.s.s.web.authentication.AnonymousAuthenticationFilter
o.s.s.web.session.SessionManagementFilter
o.s.s.web.access.ExceptionTranslationFilter
o.s.s.web.access.intercept.FilterSecurityInterceptor

3. The final destination servlet is the Spring MVC dispatcher servlet.


4. The main strategy interface for authentication is AuthenticationManager which only has one method.

public interface AuthenticationManager {

  Authentication authenticate(Authentication authentication)
    throws AuthenticationException;

}

5. The most commonly used implementation of AuthenticationManager is ProviderManager, which delegates to a chain of AuthenticationProvider instances.


public interface AuthenticationProvider {

Authentication authenticate(Authentication authentication)
	throws AuthenticationException;

	boolean supports(Class<?> authentication);

}


6. A ProviderManager can support multiple different authentication mechanisms in the same application by delegating to a chain of AuthenticationProviders. If a ProviderManager doesn’t recognise a particular Authentication instance type it will be skipped.


7. Sometimes an application has logical groups of protected resources (e.g. all web resources that match a path pattern /foo/**), and each group can have its own dedicated AuthenticationManager. Often, each of those is a ProviderManager, and they share a parent. The parent is then a kind of "global" resource, acting as a fallback for all providers.

The most important feature of this dispatch process is that only one chain ever handles a request.


8. At a high level, you can see that there are 4 major components that are responsible for much of the heavy lifting:

AbstractAuthenticationProcessingFilter:- It is found in web-based authentication requests. Processes the incoming request containing form POST, SSO information, or other user-provided credentials. Creates a partially filled Authentication object to pass user credentials along the chain of responsibility.


AuthenticationManager:- It is responsible for validating the user's credentials, and either throwing specific exceptions (in case of authentication failure), or filling out the Authentication object completely, notably including authority information.


AuthenticationProvider:- It is responsible for providing credential validation to the AuthenticationManager. Some AuthenticationProvider implementations partially base their acceptance of credentials on a credential store, such as a database.


Authentication:- is an interface and stores details of the user's identifier (for example, username), credentials (for example, password), and one or more authorities (o.s.s.core. GrantedAuthority) which the user has been given. A developer will commonly use the Authentication object to retrieve details about the authenticated user, or in a custom authentication implementation he/she will augment the Authentication object with additional application-dependent information.


9. Let's get into a little more detail and look specifically at the classes involved in the processing of a web-based username and password authentication request:

Let's take the abstract workflow seen in the high-level diagram and mentally bring it forward to work through this concrete implementation of form-based authentication. You can see that the UsernamePasswordAuthenticationFilter is responsible (through delegation from its abstract superclass) for creating the UsernamePasswordAuthenticationToken (an implementation of the Authentication interface), and partially populating it based on information in the HttpServletRequest.


4) Customizing Authentication Managers


Spring Security provides some configuration helpers to quickly get common authentication manager features set up in your application. The most commonly used helper is the AuthenticationManagerBuilder which is great for setting up in-memory, JDBC or LDAP user details, or for adding a custom UserDetailsService. Here’s an example of an application configuring the global (parent) AuthenticationManager:



@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

  @Autowired
  DataSource dataSource;

   ... // web stuff here

  @Override
  public void configure(AuthenticationManagerBuilder builder) {
  builder
  .jdbcAuthentication()
  .dataSource(dataSource)
  .withUser("dave")
  .password("secret").roles("USER");
  }

}

@Override
public void configure(AuthenticationManagerBuilder builder) throws Exception {
    builder
            .ldapAuthentication()
            .userDnPatterns("uid={0},ou=people")
            .groupSearchBase("ou=groups")
            .contextSource()
          .url("ldap://localhost:8389/dc=springframework,dc=org")
            .and()
            .passwordCompare()
            .passwordEncoder(new BCryptPasswordEncoder())
            .passwordAttribute("userPassword");
}


NOTE:- Spring Security in the web tier is currently tied to the Servlet API, so it is only really applicable when running an app in a servlet container, either embedded or otherwise. It is not, however, tied to Spring MVC or the rest of the Spring web stack, so it can be used in any servlet application, for instance one using JAX-RS.

コメント


Drop Me a Line, Let Me Know What You Think

Thanks for submitting!

© 2023 by Train of Thoughts. Proudly created with Wix.com

bottom of page