Wednesday, May 23, 2018

Spring Security With Spring Boot Tutorial | Spring Security Login Example

Spring Security With Spring Boot Tutorial | Spring Security Login Example


Before diving into this implementation, I would suggest you to look at Spring Security Introduction first.

Let's Start

Most of the Web Applications uses custom login page with custom authentication,So lets go with it.

 
 <html>
 <body>
 <form method="post" action="/login">
 ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
                     ${logoutmsg}
 UserName <input type="text" name="username"/>
 <br/>
 Password <input type="password" name="password"/>
 <br/>
 <input type="submit">
 </form>
 </body>
 </html>
 
 
 
Login page is ready,Method should be post and action "/login" to invoke spring security,The EL tag ${sessionScope) will display recent exception message thrown by the springs.

Lets create a user entity now.


import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.validator.constraints.NotBlank;

public class User {
 

 @Id
    @GeneratedValue(strategy = GenerationType.AUTO)    
    private Long userId;

    public Long getUserId() {
  return userId;
 }

 public void setUserId(Long userId) {
  this.userId = userId;
 }

 public String getUsername() {
  return username;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public String getPassword() {
  return password;
 }

 public void setPassword(String password) {
  this.password = password;
 }

 public String getRole() {
  return role;
 }

 public void setRole(String role) {
  this.role = role;
 }

 @NotBlank
 private String username;   

    @NotBlank
    private String password;   
 
    @NotBlank
 private String role;
}

When the username and password is submitted from login page,the security config file which extends WebSecurityConfigurerAdapter will be invoked.
Custom Authenticator is used in below example

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

 @Autowired 
 private CustomUserDetailsService userDetailsService;
 

@Autowired
CustomAuthentication customauthentication;
 
 @Autowired
 public void configure(AuthenticationManagerBuilder auth) throws Exception {    
  auth.authenticationProvider(customauthentication); //The Custom Authenticator is used here.
 } 
 

 @Override
 protected void configure(HttpSecurity http) throws Exception {

 //CSFR is disabled,if you dont know what csrf is,Spring has a beautiful documentaion about it ,Check it out.
 http.csrf().disable();
 
 //Login,logout page and resources are permitted for all users
 http.authorizeRequests().antMatchers("/","/login","/logout","/resources/**").permitAll();
 
 
  //userInfo page requires login as ROLE_USER or ROLE_ADMIN.
     // If no login, it will redirect to /login page.
        http.authorizeRequests().antMatchers("/userInfo").access("hasAnyRole('ROLE_USER', 'ROLE_ADMIN')");
 
     // For ADMIN only.
        http.authorizeRequests().antMatchers("/admin").access("hasRole('ROLE_ADMIN')");

 //Login and logout configurations 
 //username and password parameter must match the login form username and password parameter
 //When the user logs out,it will be redirected to login page as specified,it is always good practice to display a logout message whwn the user logs
 out,To display a logout message,follow the last snippet.
 //On Successful login user will be redirected to "/index" page as specified below else back to login page.
 http.authorizeRequests().and().
 formLogin().loginProcessingUrl("/login").loginPage("/login").defaultSuccessUrl("/index")
 .failureUrl("/login?error=true").usernameParameter("username").passwordParameter("password").
 and().
 logout().logoutSuccessUrl("/login?logout");

 
  // If no login, it will redirect to /login page.
 http.authorizeRequests().antMatchers("/**").authenticated();
 
 //Handling Access Denied Request
 http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/accessdenied");
 
 }
 
}


Simple Custom Authentication would look like below one,logic might change based on your requirements.

public class CustomAuthentication implements AuthenticationProvider {
 
@Autowired
private UserRepository userrepository;

 @Override
 public Authentication authenticate(Authentication auth)
   throws AuthenticationException {
  
   String username = auth.getName();
   String password = auth.getCredentials().toString();

  User user = userrepository.findByUsername(username);
  if(user==null){
   throw new BadCredentialsException("Username Not Found");
  }
  
  if(!password.equals(user.getPassword)){
   throw new BadCredentialsException("Username Or Password Is invalid");
  }
   
  
  return new UsernamePasswordAuthenticationToken(username,password, 
    Arrays.asList(new SimpleGrantedAuthority(user.getRole()))); 
 }

 @Override
 public boolean supports(Class<?> arg0) {
  return true;
 }

}

In the above code exception is thrown with a relevant message if the condition fails,these messages are displayed on login page by EL tag ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}.

If everything checks out,user will be forwarded to welcome page as specified in the security config file.

On Successfully logging out , /login is called which hits the controller,You can set the logout message there as shown below

@RequestMapping(value="/login")
public String showLogin(String error,String logout,Model model) {
 
 if(logout!=null)
  model.addAttribute("logoutmsg", "You've been logged out Successfully");
 
    return "login";
}


Download Source Code

Share:

0 comments:

Post a Comment