By Marone: December 2019

Goal

This is part II of a series of articles on Spring security topic, The first part with basic authenticationcan be found here. Instead of using inMemoryAuthentication we will use for the frist time AuthenticationProvider to authenticate the users, afterwards we implement a custom UserDetailsService to load users.

Used technologies

JDK 1.8
Maven 3.2 (Spring boot 2.x and Spring security 5.x)

Maven


Rest api


In given controller, we have three API methods

Configuration with AuthenticationProvider


  • AuthenticationProvider provides two methods authenticateandsupports
  • In Line (13-18) are all urls public except/protectedand/admin, for the urls below we force Basic authentication:
    • The/protected url is protected by the USER role
    • The/admin url is protected by the ADMIN role
  • We pass a custom AuthenticationProvider to AuthenticationManagerBuilder

The custom AuthenticationProvider


  • In this tutorial we use a custom AuthenticationProvider with to two dummy users
  • In theauthenticatemethode we check if the passed credentials match
  • This methode returns aAuthentication object, that contains username, password and a list auf authorities, we pass the user's role as SimpleGrantedAuthority
  • At that point, the user is authenticated super.setAuthenticated(true);
  • The only missing thing here is the authorization, that will happend later. Spring will check internally if the passed authority matches what we configured in SpringSecurityConfig

Let's test


  • Calling http://localhost:8080/protected without credentials returns "401, Unauthorized"
  • The admin endpoint expect user with Role=Admin, passing a user with other Role will cause a "403, Forbidden"

The custom CustomUserDetailsService


  • In this tutorial we use a custom AuthenticationProvider with to two dummy users
  • The passwords have {noop}prefixes which indicates that NoOpPasswordEncoder will be used
  • This methode loadUserByUsername returns a user based on the username
  • This methode mapUserDetails maps the internal user to UserDetails
  • The UserDetails contains username, password and a SimpleGrantedAuthority with Role = ROLE_ADMIN
  • The ProviderManager will check if password match, if every thing is fine the user becomes authenticated
  • Later Spring will check internally if the passed authority matches what we configured in SpringSecurityConfig

Adjusting SpringSecurityConfig

We pass CustomUserDetailsService. Now the curl commands will retrun the same result


References


The complete code can be found in GitHub