Grant or restrict permissions to routes through roles in Spring Security in Spring Boot

2

Good morning everyone, I have an application in Spring Boot in which I implemented Spring Security. I have managed to log in and have access to all the routes once logged in, and also restriction to all routes when the session has not been started. In my system I have a list of Users - > Roles - > Roles_Menu and Menu as seen in the following image:

I would like to know if it is possible to grant permissions to each role only to the routes that are registered in the database.

Although in the implementation of Spring Security a List of routes is included for each user, this does not make any restriction to the routes whose access is not reflected in said list.

Here is the detail of my code:

This is my User class

package com.escuelaapp.EscuelaApp.entity;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import com.fasterxml.jackson.annotation.JsonIgnore;

/**
 *
 * @author ALEJO
 */
@Entity
@Table(name = "user")
public class User implements UserDetails{

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "document")
    private long document;
    @Basic(optional = false)
    @Column(name = "first_name")
    private String firstName;
    @Column(name = "second_name")
    private String secondName;
    @Basic(optional = false)
    @Column(name = "surname")
    private String surname;
    @Column(name = "second_surname")
    private String secondSurname;
    @Basic(optional = false)
    @Column(name = "username")
    @NotNull
    @Size(min=2,max=10) 
    private String userName;
    @Column(name = "email")
    private String email;
    @Basic(optional = false)
    @Column(name = "password")
    @NotNull
    private String password;
    @Basic(optional = false)
    @Column(name = "state")
    private short state;

    @JoinColumn(name="profile_id")
    @ManyToOne(targetEntity=Profile.class,fetch=FetchType.EAGER)
    private Profile profile;


    public User() {
    }

    public User(Integer id) {
        this.id = id;
    }

    public User(Integer id, long document, String firstName, String surname, String username, String password,
            short state) {
        this.id = id;
        this.document = document;
        this.firstName = firstName;
        this.surname = surname;
        this.userName = username;
        this.password = password;
        this.state = state;
    }



    public User(@NotNull @Size(min = 2, max = 10) String userName, @NotNull String password) {
        super();
        this.userName = userName;
        this.password = password;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public long getDocument() {
        return document;
    }

    public void setDocument(long document) {
        this.document = document;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSecondName() {
        return secondName;
    }

    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getSecondSurname() {
        return secondSurname;
    }

    public void setSecondSurname(String secondSurname) {
        this.secondSurname = secondSurname;
    }

    public String getUserName() {
        return userName;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @JsonIgnore
    public String getPassword() {
        return password;
    }

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

    public short getState() {
        return state;
    }

    public void setState(short state) {
        this.state = state;
    }

    public Profile getProfile() {
        return profile;
    }

    public void setProfile(Profile profile) {
        this.profile = profile;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", document=" + document + ", firstName=" + firstName + ", secondName=" + secondName
                + ", surname=" + surname + ", secondSurname=" + secondSurname + ", userName=" + userName + ", email="
                + email + ", password=" + password + ", state=" + state + ", profile=" + profile + "]";
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getUsername() {
        return this.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }
}

This is the Profile Class (or ROL)

package com.escuelaapp.EscuelaApp.entity;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="profile")
public class Profile {

    @Id
    @Column(name="id")
    private int id;

    @Column(name="name")
    private String name;

    @OneToMany(mappedBy="profile")
    private List<User> users;


    @OneToMany(fetch=FetchType.EAGER,mappedBy="profileId")
    private List<ProfileMenu> profileMenus;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Transient
    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
    @Transient
    public List<ProfileMenu> getProfileMenus() {
        return profileMenus;
    }

    public void setProfileMenus(List<ProfileMenu> profileMenus) {
        this.profileMenus = profileMenus;
    }

    @Override
    public String toString() {
        return "Profile [id=" + id + ", name=" + name + ", users=" + users + "]";
    }   
}

This is the Menu class

package com.escuelaapp.EscuelaApp.entity;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "menu")
public class Menu {

    @Id
    @Column(name = "id")
    private int id;
    @Column(name = "name")
    private String name;
    @Column(name = "url")
    private String url;
    @Column(name = "icon")
    private String icon;

    @OneToMany( mappedBy = "menus")
    private List<ProfileMenu> profileMenu;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    @Transient
    public List<ProfileMenu> getProfileMenu() {
        return profileMenu;
    }

    public void setProfileMenu(List<ProfileMenu> profileMenu) {
        this.profileMenu = profileMenu;
    }

    @Override
    public String toString() {
        return "Menu [id=" + id + ", name=" + name + ", url=" + url + ", icon=" + icon + ", profileMenu=" + profileMenu
                + "]";
    }

}

And this is the class that relates the ROLE with the Menu

package com.escuelaapp.EscuelaApp.entity;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="profile_menu")
public class ProfileMenu {


    @Id
    @Column(name="id")
    private int id;
    @ManyToOne(targetEntity=Profile.class)
    @JoinColumn(name="profile_id")
    private Profile profileId;
    @ManyToOne(fetch=FetchType.EAGER,targetEntity=Menu.class)
    @JoinColumn(name="menu_id")
    private Menu menus;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public Profile getProfileId() {
        return profileId;
    }
    public void setProfileId(Profile profileId) {
        this.profileId = profileId;
    }
    public Menu getMenus() {
        return menus;
    }
    public void setMenus(Menu menus) {
        this.menus = menus;
    }
    @Override
    public String toString() {
        return "ProfileMenu [id=" + id + ", profileId=" + profileId + ", menus=" + menus + "]";
    }   
}

This is the configuration of my User table with Spring Security

package com.escuelaapp.EscuelaApp.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.escuelaapp.EscuelaApp.entity.User;
import com.escuelaapp.EscuelaApp.repository.UserRepository;

@Service("UserServiceSecurity")
public class UserServiceSecurity implements UserDetailsService {

    @Autowired
    @Qualifier("UserRepository")
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUserName(username);
        List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
        user.getProfile().getProfileMenus().stream().forEach((x) -> {
            auths.add(new SimpleGrantedAuthority(x.getMenus().getUrl()));
            //System.out.println(x.getMenus().getUrl());
        });
        return userBuiler(user, auths);
    }

    private org.springframework.security.core.userdetails.User userBuiler(User user,
            List<GrantedAuthority> authorities) {

        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
                authorities);
    }
}

This is the configuration of Spring Security by http, according to the official documentation

package com.escuelaapp.EscuelaApp.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("UserServiceSecurity")
    private UserDetailsService userService;

    @Autowired
    public void ConfigureGlobal(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }   

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .antMatchers("/inicio").permitAll()
            .antMatchers("/bower_components/**","/imgs/**","/css/**","/js/**","/fonts/**","/favicon.ico").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .permitAll()
            .loginPage("/inicio")           
            .failureUrl("/inicio?error")
            .loginProcessingUrl("/loginValidation")
            .usernameParameter("username")
            .passwordParameter("password")
            .defaultSuccessUrl("/dashboard")            
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/inicio?logout")
            .permitAll()
        ;       
    }

}

The information in Database is as follows:

select U.username, P.name, M.url from user U
join profile P on P.id=U.profile_id
join profile_menu  PM on PM.profile_id=P.id
join menu M on M.id=PM.menu_id

Finally in the controller I have the following routes, and I want for example that the user has no access to the non-Administrator route or to any other that is not registered in the database

package com.escuelaapp.EscuelaApp.controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.escuelaapp.EscuelaApp.configuration.EscuelappProperties;
import com.escuelaapp.EscuelaApp.entity.User;
import com.escuelaapp.EscuelaApp.model.CustomUserDetail;
import com.escuelaapp.EscuelaApp.model.LoggedUser;

@Controller
public class LoginController {

    private static final Log LOGGER = LogFactory.getLog(LoginController.class);

    @Autowired
    EscuelappProperties properties;  

    @GetMapping({"/inicio","/"})
    public String index(Model model,@RequestParam(required=false) String error, @RequestParam(required=false) String logout) {
        properties.initSliders();
        model.addAttribute("user", new User());
        model.addAttribute("prop", properties);
        model.addAttribute("error", error);
        model.addAttribute("logout", logout);
        return "index";
        //return "redirect:/login";
    }   


    @GetMapping("/dashboard")
    public ModelAndView dashboard() {
        ModelAndView mav = new ModelAndView("dashboard");
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         //LoggedUser principal = (LoggedUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         //CustomUserDetail principal = (CustomUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
         //User user = principal.getUser();     
        //mav.addObject("user", user);
        mav.addObject("username", user.getUsername());
        return mav;
    }

    @GetMapping("/usuarios")
    public @ResponseBody String usuarios() {
        return "Tiene acceso a la ruta:  usuarios";
    }

    @GetMapping("/permisos")
    public @ResponseBody String permisos() {
        return "Tiene acceso a la ruta:  permisos";
    }   

    @GetMapping("/noAdministrador")
    public @ResponseBody String noAdmin() {
        return "Tiene acceso a la ruta:  no Admin";
    }   


}

I appreciate your collaboration in relation to the information that you can provide me to understand how Spring Security works or if this validation of permissions by profiles or roles I have to do it manually.

    
asked by Camilo Calderón Tapia 04.11.2018 в 20:06
source

2 answers

1

I'm basing myself on these Baeldung articles: "Role and Privilege for Spring Security registration" and "Spring Security Granted Authority vs. Role" . For more details you can reference this Github project .

First you will need to have 3 Entity Objects that correspond to the User, Role and Permission tables in your database:

User Model :

@Entity
public class User {

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

    private String firstName;
    private String lastName;
    private String email;
    private String password;
    private boolean enabled;
    private boolean tokenExpired;

    @ManyToMany
    @JoinTable( 
        name = "users_roles", 
        joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) 
    private Collection<Role> roles;
}

Role Model :

@Entity
public class Role {

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

    private String name;
    @ManyToMany(mappedBy = "roles")
    private Collection<User> users;

    @ManyToMany
    @JoinTable(
        name = "roles_privileges", 
        joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
    private Collection<Privilege> privileges;   
}

Permit Model :

@Entity
public class Privilege {

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

    private String name;

    @ManyToMany(mappedBy = "privileges")
    private Collection<Role> roles;
}

Once you have the entities, we proceed to create a component that initializes the database with the permissions and valid roles (this is totally optional, you can configure it directly from the DB without making use of this):

@Component
public class InitialDataLoader implements ApplicationListener<ContextRefreshedEvent> {

    boolean alreadySetup = false;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PrivilegeRepository privilegeRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public void onApplicationEvent(ContextRefreshedEvent event) {

        // Verificamos que no se haya realizado la inicializacion previamente
        if (alreadySetup) {
            return;
        }

        // Aqui se deben crear los permisos
        Privilege readPrivilege = createPrivilegeIfNotFound("PERMISO_LECTURA");
        Privilege writePrivilege = createPrivilegeIfNotFound("PERMISO_ESCRITURA");
        Privilege otherPrivilege = createPrivilegeIfNotFound("PERMISO_OTRO");

        //Asociamos los permisos a roles
        List<Privilege> adminPrivileges = Arrays.asList(readPrivilege, writePrivilege, otherPrivilege);        
        Role adminRole = createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);

        List<Privilege> userPrivileges = Arrays.asList(readPrivilege, otherPrivilege);
        Role userRole = createRoleIfNotFound("ROLE_USUARIO", Arrays.asList(userPrivileges));

        // Creamos un usuario Test con rol Admin
        User user = new User();
        user.setFirstName("Test");
        user.setLastName("Test");
        user.setPassword(passwordEncoder.encode("test"));
        user.setEmail("[email protected]");
        user.setRoles(Arrays.asList(adminRole));
        user.setEnabled(true);
        userRepository.save(user);

        alreadySetup = true;
    }

    @Transactional
    private Privilege createPrivilegeIfNotFound(String name) {

        Privilege privilege = privilegeRepository.findByName(name);
        if (privilege == null) {
            privilege = new Privilege(name);
            return privilegeRepository.save(privilege);
        }
        return privilege;
    }

    @Transactional
    private Role createRoleIfNotFound(String name, Collection<Privilege> privileges) {

        Role role = roleRepository.findByName(name);
        if (role == null) {
            role = new Role(name);
            role.setPrivileges(privileges);
            return roleRepository.save(role);
        }
        return role;
    }
}

Eye, with regard to the above:

  • In Spring, normally what we have referred to as Permiso ( Privilege ), they call it Role or (Granted) Authority
  • The prefix ROLE must be used when defining role names (or at least in versions prior to Spring Security 4). Of course this can be changed with Spring configurations.
  • Having the above, the security configuration file (which in this case extends from WebSecurityConfigurerAdapter ) can be edited as follows:

    Security Config

    import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.core.userdetails.UserDetailsService;
    ///...
    
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        ///...
    
        @Autowired
        private CustomUserDetailsService customUserDetailsService;
    
        ///...
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
           // ...
           .antMatchers("/protegido-por-role").hasRole("ROLE_USUARIO")
           .antMatchers("/protegido-por-authority").hasAuthority("PERMISO_LECTURA")
           // ...
        }
    
        @Bean
        public DaoAuthenticationProvider authProvider() {
            final CustomAuthenticationProvider authProvider = new CustomAuthenticationProvider();
            authProvider.setUserDetailsService(CustomUserDetailsService);
            // ...
            return authProvider;
        }
    }
    

    As you can see, roles and permissions assigned to individual routes are configured. In turn, you must specify a Bean of type DaoAuthenticationProvider that indicates that sevicio ( UserDetailsService ) must use to authenticate and obtain the information of the user that is logged in at this moment.

    User Details Service :

    @Service
    @Transactional
    public class CustomUserDetailsService implements UserDetailsService {
    
        @Autowired
        private UserRepository userRepository;
    
        @Autowired
        private IUserService service;
    
        @Autowired
        private MessageSource messages;
    
        @Autowired
        private RoleRepository roleRepository;
    
        @Override
        public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    
            User user = userRepository.findByEmail(email);
            if (user == null) {
                throw new UsernameNotFoundException("No se encontre el usuario con email: " + email);
            }
    
            List<GrantedAuthority> grantedAuthorities = getAuthorities(user.getRoles());
    
            return new org.springframework.security.core.userdetails.User(
              user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, grantedAuthorities);
        }
    
        private Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roles) {
            return getGrantedAuthorities(getPrivileges(roles));
        }
    
        private List<String> getPrivileges(Collection<Role> roles) {
    
            List<String> privileges = new ArrayList<>();
            List<Privilege> collection = new ArrayList<>();
            for (Role role : roles) {
                collection.addAll(role.getPrivileges());
            }
            for (Privilege item : collection) {
                privileges.add(item.getName());
            }
            return privileges;
        }
    
        private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
            List<GrantedAuthority> authorities = new ArrayList<>();
            for (String privilege : privileges) {
                authorities.add(new SimpleGrantedAuthority(privilege));
            }
            return authorities;
        }
    }
    

    In short the provider must do some logic to determine if the credentials provided by the user are valid.

    Authentication Provider :

    public class CustomAuthenticationProvider extends DaoAuthenticationProvider {
    
        @Autowired
        private UserRepository userRepository;
    
        @Override
        public Authentication authenticate(Authentication auth) throws AuthenticationException {
            final User user = userRepository.findByEmail(auth.getName());
            if ((user == null)) {
                throw new BadCredentialsException("Invalid username or password");
            }
    
            // logica que autentica al usuario ...
    
            final Authentication result = super.authenticate(auth);
            return new UsernamePasswordAuthenticationToken(user, result.getCredentials(), result.getAuthorities());
        }
    
        @Override
        public boolean supports(Class<?> authentication) {
            return authentication.equals(UsernamePasswordAuthenticationToken.class);
        }
    }
    

    From what I've seen your code, you have something very similar. I think that by playing a little with this and the examples on which I base you can get what you need =)

        
    answered by 08.11.2018 в 20:00
    0

    To solve my problem, I have configured the role as an Authority, including the prefix ROLE _

    @Service("UserServiceSecurity")
    public class UserServiceSecurity implements UserDetailsService {
    
        @Autowired
        @Qualifier("UserRepository")
        private UserRepository userRepository;
    
        private String ROLE_PREFIX = "ROLE_";
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userRepository.findByUserName(username);
            List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
            auths.add(new SimpleGrantedAuthority(ROLE_PREFIX+user.getProfile().getName()));
            user.getProfile().getProfileMenus().stream().forEach((x) -> {
                auths.add(new SimpleGrantedAuthority(x.getMenus().getUrl()));
            });
            return userBuiler(user, auths);
        }
    
        private org.springframework.security.core.userdetails.User userBuiler(User user,
                List<GrantedAuthority> authorities) {
            return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
                    authorities);
        }
    }
    

    And then I added add @PreAuthorize ("hasRole ('ROLENAME')") in a controller or method or Controller:

    @Controller
    
    @PreAuthorize("hasRole('DOCENTE')")
    @RequestMapping("/docente")
    public class TeacherController {
    
        //@PreAuthorize("hasAuthority('/docente/registrar-asistencia')")
        @GetMapping("/registrar-asistencia")
        public @ResponseBody String registrarAsistencia() {
            return "Tiene acceso a la ruta:  registrarAsistencia";
        }
    
        @GetMapping("/generar-boletin")
        public @ResponseBody String generarBoletin() {
            return "Tiene acceso a la ruta:  generar-boletin";
        }
    
    }
    
        
    answered by 09.11.2018 в 14:55