Questions Spring Boot Web App - Android

1

A few weeks ago I finished the project of a web system that does basic cruds, I used Java, Maven, Spring Boot, Hibernate, Bootstrap + Thymeleaf pro frontend, etc ... And I deployed to Heroku using the bank of PostgreSQL Data

Now I'm starting to develop for Android and I want to create an app with a login screen and a dashboard, I'm still working on the layout. The question is: For android is not at all recommended, so from what I read, access an external database directly. That is, the ideal is to create an API that bridges the database. So, do I have to rewrite my entire application or can I simply implement new RestFul controllers or modify my controllers for my Android app to access the data?

NOTE: In my app I want the user to authenticate, but in my web app I did not use any framework for authentication, like Stormpath. Am I going to need to change that? Because the idea is to use the system in both the browser and the application.

I'll leave a code snippet of one of the Controller below:

@RequestMapping(value = "/sac/registration", method = RequestMethod.POST)
public ModelAndView createNewUser(@Valid User newUser, BindingResult bindingResult, String password, String role, RedirectAttributes attributes) {
    ModelAndView modelAndView = new ModelAndView();

    // Checks if already exists a user with the provided email, to avoid duplicity.
    User userExists = userService.findUserByEmail(newUser.getEmail());

    // Search for the authenticated user
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    User userAuthenticated = userService.findUserByEmail(auth.getName());

    if (userExists != null && password.length() < 5 && bindingResult.hasErrors()) {
        bindingResult
                    .rejectValue("email", "error.user",
                            "Já existe usuário com este e-mail!");
        return registration(newUser);
    }else
        if (password.length() < 5 || bindingResult.hasErrors()) {
            return registration(newUser);
        }else
            if (userExists != null || bindingResult.hasErrors()) {
                bindingResult
                            .rejectValue("email", "error.user",
                                    "Já existe usuário com este e-mail!");              
                return registration(newUser);               
            } else {
                userService.saveUser(newUser, role);
                attributes.addFlashAttribute("successMessage", "Usuário cadastrado com sucesso!");
                modelAndView.addObject("role", roleService.findAllRoles());
                modelAndView.addObject("userName", userAuthenticated.getName() + " (" + userAuthenticated.getEmail() + ")");
                modelAndView.setViewName("redirect:/sac/registration");         
            }

    return modelAndView;

}

EDIT:

System authentication is now done using Spring Security. Will I need to change all system authentication so my Android App can access? Below I will leave the codes used for authentication:

SecurityConfiguration.java

@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

/*
 * @author: Cisino Junior
 */

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@Autowired
private UserDetailsService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    auth
        .userDetailsService(userDetailsService)
        .passwordEncoder(bCryptPasswordEncoder);

}

@Override
protected void configure(HttpSecurity http) throws Exception {      
    http.
        authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/login").permitAll()
            .antMatchers("/access-denied").permitAll()
            .antMatchers("/sac/registration").hasAuthority("ADMIN")
            .antMatchers("/sac/consultarUsuarios").hasAuthority("ADMIN")
            .antMatchers("/sac/index").hasAnyAuthority("ADMIN", "SUPPORT")
            .antMatchers("/sac/**").hasAnyAuthority("ADMIN", "SUPPORT").anyRequest()                
            //.authenticated().and().csrf().disable().formLogin()
            .authenticated().and().formLogin()
            .loginPage("/login").failureUrl("/login?error=true")
            .defaultSuccessUrl("/sac/index")
            .usernameParameter("email")
            .passwordParameter("password")
            .and().logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login").and().exceptionHandling()
            .accessDeniedPage("/access-denied");
}

@Override
public void configure(WebSecurity web) throws Exception {
    web
       .ignoring()
       .antMatchers("/resources/**","/static/**", "/css/**", "/js/**", "/font-awesome/**", "/fonts/**");
} }

UserServiceImpl.java

@Service("userService")

@Transactional public class UserServiceImpl implements UserService, UserDetailsService {     / *      * @author: Cisino Junior      * /

@Autowired
private UsuarioRepository userRepository;

@Autowired
private RoleRepository roleRepository;

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;


@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    User user = userRepository.findByEmail(email);
    List<GrantedAuthority> authorities = getUserAuthority(user.getRoles());
    return buildUserForAuthentication(user, authorities);
}

private List<GrantedAuthority> getUserAuthority(Set<Role> userRoles) {
    Set<GrantedAuthority> roles = new HashSet<GrantedAuthority>();
    for (Role role : userRoles) {
        roles.add(new SimpleGrantedAuthority(role.getRole()));
    }

    List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(roles);
    return grantedAuthorities;
}

private UserDetails buildUserForAuthentication(User user, List<GrantedAuthority> authorities) {
    return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), user.getActive(), true, true, true, authorities);
}}
    
asked by anonymous 21.08.2017 / 20:22

1 answer

1

The ideal would be to have an api that both your front and your mobile app could consume ... But since everything is already written, you can reuse the other layers (service, repository and etc) that you have already written, but you need implement the endpoints that your mobile app will consume.

You are already using a framework that takes care of authentication, from one searched in OAuth or JWT with Spring Boot.

    
22.08.2017 / 16:10