2
votes

I have a problem with registration permissions in Spring Security
I can't do the methods register

I tried to set access to each path but it didn't help

Controller

@RestController
public class UserController {

    private UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/register")
        public Long register(@RequestBody User user){
        return userService.register(user);
    }
}

SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    private UserDetailsServiceImpl userDetailsService;

    public SecurityConfig(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.headers().disable();
        http.authorizeRequests().
                antMatchers("/").permitAll()
                .antMatchers("/register").permitAll();
    }
}

UserSerice

@Service
public class UserService {

    private UserRepository userRepository;
    private PasswordEncoder passwordEncoder;

    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    public Long register(User user){
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userRepository.save(user);
        return user.getId();
    }
}

User Model

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

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.*;

@Entity
public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String userName;
    private String lastName;
    private String password;
    private String role;       

    public User() {
    }

   ..get and set...

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> listRole = new ArrayList<GrantedAuthority>();

        listRole.add(new SimpleGrantedAuthority(role));
        return listRole;
    }

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

    @Override
    public String getUsername() {
        return userName;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

Error

java.lang.IllegalArgumentException: A granted authority textual representation is required at org.springframework.util.Assert.hasText(Assert.java:284) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE] at org.springframework.security.core.authority.SimpleGrantedAuthority.(SimpleGrantedAuthority.java:38) ~[spring-security-core-5.2.2.RELEASE.jar:5.2.2.RELEASE] at com.xxx.xx.models.User.getAuthorities(User.java:71) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]

3

3 Answers

4
votes

In your User model class, make sure that a role is set, for your getAuthorities() method to work.

The error you are getting hints to the fact that you are doing a "new SimpleGrantedAuthority" with a "null" role.

 @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> listRole = new ArrayList<GrantedAuthority>();

        listRole.add(new SimpleGrantedAuthority(role)); // this is the problematic line!
        return listRole;
    }

If you don't have a role, then simply return an empty list instead.

 @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
         return Collections.emptyList();
    }
0
votes

This is my JSON and I use defult ROLE. I try return an empty list but I have this same error

{
  "accountNonExpired": true,
  "accountNonLocked": true,
  "authorities": [
    {
      "authority": "string"
    }
  ],
  "credentialsNonExpired": true,
  "enabled": true,
  "id": 0,
  "lastName": "Piotr",
  "name": "Piotr",
  "password": "Piotr",
  "role": "ROLE_ADMIN",
  "username": "Piotr"
}

Error form POSTMAN

**"timestamp": "2020-04-01T15:20:05.670+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "JSON conversion problem: A granted authority textual representation is required; nested exception is com.fasterxml.jackson.databind.JsonMappingException: A granted authority textual representation is required\n at [Source: (PushbackInputStream); line: 4, column: 18] (through reference chain: com.xxx`enter code here`.xxx.models.User[\"authorities\"])",
    "path": "/register"
}**
0
votes

I believe you have to create user object like

new org.springframework.security.core.userdetails.Usersername,passwordEncoder.encode user.getPass ()), grantedAuthorityList);

this work form me!

@Service  
public class UserSecurityService implements UserDetailsService {

@Autowired
YourRepository yourRepository;


@Autowired
PasswordEncoder passwordEncoder;


@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
    User user = yourRepository.findUserByUser(username);

    List<String> listRoles = new ArrayList<>();
    //List<UserRoles> userRoles = user.getUserRoleList();

    user.getUserRoleList().forEach(role->listRoles.add(role.getRole().getRole()));// get role from database - usa il tuo modo **

    grantedAuthorityList = listRoles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());


    //*** important ****
    return new org.springframework.security.core.userdetails.User(username,
            passwordEncoder.encode(user.getPass()), grantedAuthorityList);


}