0

Using spring security to secure Rest API.

by integrating spring security all goes fine, until I try to develop my own controller which gonna handle the user authentication based on sessionManagement.

Here is my spring security configuration java code :

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationEntryPoint authEntryPoint;

    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 
     * Kind of links provided based on the User authorises USER - SUPER_USER - SIMPLE_USER ..etc
     * 
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        .and()
        .authorizeRequests()
        .antMatchers("/loginPage").permitAll()
        .antMatchers("/securetAPI1/**","/securetAPI2/**","/securetAPI3/**","/securetAPI5/**").access("hasRole('ADMIN')")
        .and().httpBasic().authenticationEntryPoint(authEntryPoint);
    }

    /**
     * Build Authentication and attach it to the appContext
     * 
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
}

Then my AuthentivationEntryPoint contains this code:

@Component
public class AuthenticationEntryPoint extends BasicAuthenticationEntryPoint {


    /**
     * Authentication Entry Point on our application which check if the user allowed or not,
     * and give response back based on servlet on the case of failure
     * 
     */
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
      throws IOException, ServletException {
        response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName());
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println("HTTP Status 401 - " + authEx.getMessage());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("MBO");
        super.afterPropertiesSet();
    }

}

And of the UserDetailsService class contain this snippet code:

@Service
public class TheUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 
     * retrieve authenticate user by his Role to verify it later if he is autorized to access the API or Not
     * 
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User retrievedUser = userRepository.findByUserName(username);
        List<GrantedAuthority> authorities = this.createUserAuthorities(retrievedUser.getUserRole());
        return (UserDetails) this.buildUserForAuthentication(retrievedUser, authorities);
    }

    private User buildUserForAuthentication(User user, List<GrantedAuthority> authorities) {
        User usr = new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
        return usr;
    }

    /**
     * give the user authority based on his Role in database, which gonna be converted by our method to SIMPLE.GRANTED.AUTHORITY
     * to be processed later in Servlet intercepting and check authorities
     * 
     * One USER can have multiple authorities for that reason the return back a List<GrantedAuthority>.
     * @param userRoles
     * @return
     */
    private List<GrantedAuthority> createUserAuthorities(Set<UserRole> userRoles) {
        Set<GrantedAuthority> authsList = new HashSet<GrantedAuthority>();
        // create user's authorities
        userRoles.forEach(userRole -> {
            authsList.add(new SimpleGrantedAuthority(userRole.getRole()));
        });
        List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(authsList);
        return Result;
    }
}

So till now when even i try to access one of this Rest API "/securetAPI1/**" "/securetAPI2/**" "/securetAPI3/**" "/securetAPI5/**" from browser its show me this spring security session authentication popup

Any one can suggest me correction or any tutorial who to build my Login RestController that submit user-sessionID and bypass the spring security authentication popup for the rest of API accessAttempt?

My RestController Login try:

@RestController
@RequestMapping(value="/")
public class LoginController {

    @Autowired
    private UserDetailsService userDetail;

    @RequestMapping(value="/loginPage", method = RequestMethod.POST)
    public void login(@RequestBody UserDto user, HttpServletResponse response) throws IOException{
        if(user.getUsername() != null && user.getPassword() != null) {
            UserDetails userDetails = userDetail.loadUserByUsername(user.getUsername());
            if(userDetails != null) {
                response.sendRedirect("/application-context/securetAPI1/");
            }
            else
                System.out.println("Failed");
        }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
shiner
  • 1
  • to answer you in a simple way- If you do not configure your login page then spring will show built in login for any URL thats secured. You just need to configure it correctly. To have some heads up please visit here [link](https://stackoverflow.com/questions/32548372/how-to-secure-rest-api-with-spring-boot-and-spring-security) . Moreover, there are many posts available, just search – Subhasish Bhattacharjee Nov 07 '18 at 15:11
  • Checkout this question https://stackoverflow.com/questions/44302457/how-can-i-implement-basic-authentication-with-jwt-authentication-in-spring-boot – 11thdimension Nov 10 '18 at 22:59

0 Answers0