By Marone: December 2019
Secure spring boot with custom authentication
Goal
This is part II of a series of articles onSpring 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.8Maven 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
authenticate
andsupports
- In Line (13-18) are all urls public except
/protected
and/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
- The
- We pass a custom AuthenticationProvider to AuthenticationManagerBuilder
The custom AuthenticationProvider
- In this tutorial we use a custom AuthenticationProvider with to two dummy users
- In the
authenticate
methode we check if the passed credentials match - This methode returns a
Authentication
object, that contains username, password and a list auf authorities, we pass the user's role asSimpleGrantedAuthority
- 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