Spring Security Series In-Memory Users Management with Custom Forms

Spring Security Series In-Memory Users Management with Custom Forms

#springboot #springsecurity #cloudnative

?Spring Boot Security is an extension of the Spring Security framework, which provides authentication, authorization, and other security features for Java applications. It seamlessly integrates with Spring Boot, making it easier to configure and customize security settings. With Spring Boot Security, you can implement various security mechanisms, such as form-based authentication, token-based authentication, and method-level authorization, to ensure the integrity and confidentiality of your application's data.

Today we are going to explore Role-based access control (RBAC), We will implement In Memory User Service with custom login page. Let Start

Step 1

First, we need to create project from spring initializer website and add the required dependencies as following.

No alt text provided for this image

Step 2

Once we imported the project in our favorite IDE IntelliJ, we need add Security Configuration as following.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
        .authorizeHttpRequests((authorize) ->
              authorize.anyRequest().authenticated()
         ).formLogin(
                        form -> form
                                .loginPage("/login")
                                .loginProcessingUrl("/login")
                                .successHandler(new AuthenticationSuccessHandlerImpl())
                                .failureUrl("/error")
                                .permitAll()
                ).logout(
                        logout -> logout
                                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                                .permitAll()
                );
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user= User.builder()
                .username("haroon")
                .password(passwordEncoder().encode("password"))
                .roles("USER")
                .build();

        UserDetails admin = User.builder()
                .username("admin")
                .password(passwordEncoder().encode("admin"))
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }
}

        

In above code the SecurityConfiguration class is a Java configuration class that provides security-related configurations for a web application. It is annotated with the @Configuration and @EnableWebSecurity annotations

The SecurityConfiguration class defines three significant beans:

  1. The passwordEncoder() bean configures the password encoder, which is responsible for encoding and verifying passwords. In this code snippet, the BCryptPasswordEncoder is used to securely store passwords.
  2. The filterChain() bean configures the security filter chain, which determines how requests are authenticated and authorized. The HttpSecurity object allows you to define various security rules and configurations for different HTTP requests. The authorizeHttpRequests() method specifies that any HTTP request should require authentication, meaning the user must be logged in. The formLogin() method specifies the use of form-based authentication, it handle success, failure and logout.
  3. userDetailsService(): This bean provides the implementation for the user details service.

Step 3

Incorporate the success handle utilized in the aforementioned security configuration in the following manner.

public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        String redirectURL = request.getContextPath();
        Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
        if (roles.contains("ROLE_ADMIN")) {
            redirectURL = "/admin";
        } else{
            redirectURL = "/welcome";
        }
        response.sendRedirect(redirectURL);
    }
}        

The onAuthenticationSuccess() method is called when a user successfully authenticates. The method takes three parameters:

  • request: The HTTP request that was made.
  • response: The HTTP response that will be sent back to the client.
  • authentication: The authentication object that contains the user's credentials.

The onAuthenticationSuccess() method is responsible for redirecting the user to the appropriate page. In this example, the method checks the user's role. If the user is an administrator, the method redirects the user to the /admin page. Otherwise, the method redirects the user to the /welcome page.

Step 4

Following the given steps, we will generate a controller class to map the welcome and login admin pages. Additionally, we will create HTML pages within the template folders.

@Controller
public class WelComeController {

    @GetMapping("/welcome")
    public String greeting() {
        return "welcome";
    }
    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }
    @GetMapping("/login")
    public String login(){
        return "login";
    }
}
         


<div class="card-body">
    <form
            method="post"
            role="form"
            th:action="@{/login}"
            class="form-horizontal"
    >
        <div class="form-group mb-3">
            <label class="control-label"> Email</label>
            <input
                    type="text"
                    id="username"
                    name="username"
                    class="form-control"
                    placeholder="Enter email address"
            />
        </div>

        <div class="form-group mb-3">
            <label class="control-label"> Password</label>
            <input
                    type="password"
                    id="password"
                    name="password"
                    class="form-control"
                    placeholder="Enter password"
            />
        </div>
        <div class="form-group mb-3">
            <button type="submit" class="btn btn-primary">Submit</button>

        </div>
    </form>
</div>         

Conclusion:

By adhering to these instructions, you will be able to generate a personalized login page and integrate role-based functionalities. In the upcoming blog post, we will explore the utilization of JPA and Spring Security to employ a database for user management. Stay tune.

you can find full source code for above example in following branch spring-security-inmemory-users-with-custom-forms

No alt text provided for this image
No alt text provided for this image

要查看或添加评论,请登录

Haroon Idrees的更多文章

社区洞察

其他会员也浏览了