The Key Component in Spring Security
- The Authentication filter is a servlet filter class that will see if the user has authenticated
- if not , it will send that requiest to authentication manager to check if the detail send by the user are correct
- if the username and password are valid, the authentication manager in turn uses authentication provider this is where the login logic or the authenication logic is defined.
- the authentication provider will not fetch the user details from the database or from LDAP or in memory, it will user user detail service for that purpose.
- it will use also password encoder becauase we dont want to store password in plain text so the password will be decoded the incoming password from the user will be encoded and then the comparision is done.
- once the authentication provider check if the authentication details the user name and password etc are correct than it will send the apporopriate response back to the authentication manager
- authentication mangeer hands it back to the authentication filter if the user details are OK
- the authentication filter will user a authentication success handler and store that authentication
- information the user entity it self in a security context, in an instance of security context, if the authentication failed it will use the authenication failure handler to send the appropriate response back to the client
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Spring Security Rocks!!";
}
}
Now check into Postman
which means not authenticated also by browser getting given below screen
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
public class MySecurityConfig {
//this will customize or to configure the security for our application as it sees a bean
//being expose out at runtime, it will use that bean to configure security instead of
//the default security, so now everything is relies on what we have to return back here.
//default security will be override with the security filter chain bean.
@SuppressWarnings("removal")
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.httpBasic();
http.authorizeHttpRequests().anyRequest().authenticated();
return http.build();
}
}
The Next Step is to configure a custom user detail service so that we need
not use the default user and its default generated UUID password
@Bean
UserDetailsService userDetailsService() {
InMemoryUserDetailsManager userDetailService = new InMemoryUserDetailsManager();
UserDetails user = User.withUsername("khan")
.password(passwordEncoder().encode("world")).authorities("read").build();
userDetailService.createUser(user);
return userDetailService;
}
@Bean
BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
1. First Method with UserDetailsService will create the User with username
and password also encode the password
2. Second method is used to decrypt the password when the user comes in and
trying to get access of the application with given password
Now Lets use Custome Authentiction Logic inside Authentication provider
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String userName = authentication.getName();
String password = authentication.getCredentials().toString();
if("khan".equals(userName) && "world".equals(password)) {
return new UsernamePasswordAuthenticationToken(userName, password, Arrays.asList());
} else {
throw new BadCredentialsException("Invalid Username Or Password");
}
}
By Given Above our custom Authentication Provider will send back our
Authentication token to the authentication manager and authentication manager will
send back to this authentication token to the authentication filter
since the authentication is successfull, it will store that username and passwod in
security context or if its fail it will throw bad credential exception which we have
added into our customer authentication provider class than will get 401 access issue
2. public boolean supports(Class<?> authentication) : this second method supports so
we need to tell that the username and password authentication, token type
this method needs to return to boolean value
@Override
public boolean supports(Class<?> authentication) {
return authentication
.equals(UsernamePasswordAuthenticationToken.class);
}
So at runtime the authentication manager passes this type within this authentication
object to see if this provider supports this type of authentication and we are
comparing it with username and password authentication token type
if they both are same yes, this provider support the username and password authentication
token type, you can use that
Complete class will be look like
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String userName = authentication.getName();
String password = authentication.getCredentials().toString();
if("khan".equals(userName) && "world".equals(password)) {
return new UsernamePasswordAuthenticationToken(userName, password, Arrays.asList());
} else {
throw new BadCredentialsException("Invalid Username Or Password");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Comments
Post a Comment