Security. Yeah, we know, it can feel like a chore. Especially when you’re just trying to build something awesome. But trust me, skipping security is like leaving your front door wide open. That’s where Spring Security comes in — it’s your trusty sidekick for locking things down in your Spring apps. Think of it as the bouncer for your code, making sure only the right people get in.
Before diving into the main part, first lets understand the difference between two widely used and similar meaning(not exaclty) words —
Authentication and Authorization
They both are related to security. Well thats true. But how does both differ from one another.
Simply put, Authentication means WHO ARE YOU?
and Authorization means WHAT DO YOU WANT TO ACCESS?
Not same right?
When we talk about authentication, we mainly mean that the person is who he is saying he is. First authentication needs to happen. In the web applications, the login pages authenticate the user if he/she is the owner of that account or not. For authentication we may need a username and a password to prove our identity.
When the authentication is done, the user enters the web application. But he/she may not have access to all the features. Here comes authorization. Authorization let us know what accesses and rights the user has.
For example, if admin is logged in, he/she has access to more number of features than a user.
Now, lets talk about Principal
In Spring security, a user sends a request along with credentials to the server. After the user is authenticated, the returned response contains an Object of Principal which has the details of currently logged in user.
In Spring boot, add the following dependency to use Spring Security :
`<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.4.4</version>
</dependency>`
Now, as the dependency is added, do we need to configure something to use Spring security?
NO
After adding the dependency, just try hitting an API and you’ll get Unauthorized.
Spring by default uses Spring security if it is added in the pom file.
Spring Security Default behaviour —
- Adds mandatory authentication for all URLs
- Adds login form(try opening the localhost url in browser)
- Handles login error
- Creates a user and a password by default.
Above, the user and password are generated by Spring security. You can find the password in the console logs when you start the application and the user is “user” by default.
Lets now talk about configuring authentication.
Step 1 : Get hold of AuthenticationManagerBuilder
Step 2 : Set the configuration on it.
What kind of authentication you want? eg. in-memory, etc.
Set the user and password
`@EnableWebSecurity
public class myClass extends WebSecurityConfigurerAdapter {
@Override
configure(AuthenticationManagerBuilder auth) {
auth.inMemoryAuthentication()
.withUser("user1")
.withPassword("password")
.roles("USER");
}
}`
AuthenticatonManager has a method called authenticate() and we use AuthenticationManagerBuilder to access it. Override the configure method which takes AuthenticationManagerBuilder object and then set what kind of authentication you want, set the username and passwords and define the role for that user.
Now, the above code is not correct because the password is in plain text.
Never store password as plain text.
Always deal with hashed password by encoding it.
How to set a password encoder?
Just expose an @bean of type PasswordEncoder because spring security keeps looking for all the beans available to find a password encoder.
@Bean
public PasswordEncoder getEncodedPassword() {
return new BCryptPasswordEncoder();
}
Now for configuring authorization, we can ovverride same method configure() but with different parameters.
`@EnableWebSecurity
public class myClass extends WebSecurityConfigurerAdapter {
@Override
configure(HttpSecurity http) {
http.authorizeRequests()
.antMatchers("/**")
.hasRole("USER");
}
}`
The above code uses configure method along with HttpSecurity object, which authorizes all the requests given using antMatchers.
Above code, will authorize all the APIs for role USER which means all the APIs are accessible only by USER role.
`@EnableWebSecurity
public class myClass extends WebSecurityConfigurerAdapter {
@Override
configure(HttpSecurity http) {
http.authorizeRequests()
.antMatchers("/**")
.hasAnyRole();
}
}`
Above code lets any role access the APIs.
`@EnableWebSecurity
public class myClass extends WebSecurityConfigurerAdapter {
@Override
configure(HttpSecurity http) {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN").
.antMatchers("/user").hasAnyRole("ADMIN","USER").
.antMatchers("/**").permitAll().
.hasAnyRole();
}
}`
In the above code, the API with /admin can only be accessed by users with ADMIN role, /user can be accessed by users with roles ADMIN and USER and all the other APIs can be accessed by every user.
Note the above sequence, if we put “antMatchers(“/**”).permitAll()” at the top, that would make all APIs accessible to every user, so here the sequence matters.
Top comments (0)