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);
}}