this post was submitted on 27 Dec 2023
5 points (100.0% liked)

The Java Programming Language

207 readers
5 users here now

Discussion of Java and java-related technologies. This includes things like:

For assistance learning Java, please go to Learn Java

founded 2 years ago
MODERATORS
 

Hello there.

I'm writing a simple REST API using Spring Boot and I just added basic HTTP authentication in it. I'm currently using Spring Boot 3.1.5 and Spring Security 6.1.5.

There are different instructions on the web about how to correctly setup basic HTTP authentication for web requests, I believe they differ according to the Spring Security version.

It seems that latest guides use implementations of the UserDetails interface, which I found rather confusing, as it is not clear for me how exactly the framework uses that. Instead, I found much easier and clear to write my own class that inherits from AuthenticationProvider and override its authenticate() method to do all fancy things for me, including checking and setting user roles.

I'd like to ask you if there is any drawback working with AuthenticationProvider that I cannot see right now, instead of newest documentation, that doesn't seem to just use default AuthenticationProvider.

Thanks!

top 3 comments
sorted by: hot top controversial new old
[–] Hotzilla@sopuli.xyz 2 points 1 year ago (1 children)

Sorry if throwing a bit of wrench in your way but in general nowadays OAuth2.0 bearer token based authentication with API's is the preferred way to do things.

This way you don't have to send the username/password to the site, just the JWT token signed by the identity provider. It is of course depending on the case, but usually frameworks support OAuth quite easily, and you don't have to worry about storing the credentials yourself.

[–] silas 1 points 1 year ago

Thanks for the reply. Yeah, I'll probably go that way once I get familiar with basic HTTP authentication in Spring.

[–] abbadon420@lemm.ee 1 points 1 year ago* (last edited 1 year ago)

I think using AuthenticationProvider is a bit overkill. I usually make a AuthenticationManager Bean. like this:

@Bean public AuthenticationManager authenticationManager(PasswordEncoder passwordEncoder, CustomUserDetailsService customUserDetailsService) throws Exception { var auth = new DaoAuthenticationProvider(); auth.setPasswordEncoder(passwordEncoder); auth.setUserDetailsService(customUserDetailsService); return new ProviderManager(auth); }

Here I provide the DoaAuthenticationProvider which is a Spring class used for Users stored in the DB. These DB-Users can implement the UserDetails interface (mine actually don't I translate it later), because that's the interface Spring Security uses to authenticate user credentials.

I also provide a CustomUserDetailsService which is a @Service class that implements the UserDetailsService interface and it's loadByUsername method, which fetches the user from the database and translates it's username, password and authority into a UserDetails instance.

Alternatively, you can make a UserDetails Bean with InmemoryAuthentication like here. This is great for practicing security, because you can skip the step of storing Users in the DB and just declare them there, but it's not good for real world applications for obvious reasons.

(p.s. I hope this answers your question, next time provide your relevant code snippets or maybe a full github repo)