Spring boot 用户角色Spring数据Rest Spring安全
我有一个错误,我真的不明白。我没有找到任何教程来解释为什么它不起作用。我有一个使用SpringSecurity的SpringBoot应用程序 当我发出此帖子请求时: 正文: 它很好用 当我发出此帖子请求时: 正文: 它很好用 但当我提出这个GET请求时: 具有正确的凭据(用户名:user,密码:pass) 它返回:Spring boot 用户角色Spring数据Rest Spring安全,spring-boot,jpa,roles,spring-data-rest,userdetailsservice,Spring Boot,Jpa,Roles,Spring Data Rest,Userdetailsservice,我有一个错误,我真的不明白。我没有找到任何教程来解释为什么它不起作用。我有一个使用SpringSecurity的SpringBoot应用程序 当我发出此帖子请求时: 正文: 它很好用 当我发出此帖子请求时: 正文: 它很好用 但当我提出这个GET请求时: 具有正确的凭据(用户名:user,密码:pass) 它返回: { "timestamp": "2020-04-22T15:04:55.032+0000", "status": 403, "error": "Forbidden",
{
"timestamp": "2020-04-22T15:04:55.032+0000",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/users"
}
我不知道为什么它返回403
附言:所有的请求都在邮递员处完成
UnoApplication.java
package com.example.Uno;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootApplication
public class UnoApplication {
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
public static void main(String[] args) {
SpringApplication.run(UnoApplication.class, args);
}
}
package com.example.Uno.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
@Data
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@ManyToMany(mappedBy = "users",targetEntity = Role.class,cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.EAGER)
private Set<Role> roles = new HashSet<>();
}
package com.example.Uno.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
@Data
@Entity
public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.LAZY)
private Set<User> users = new HashSet<>();
}
package com.example.Uno.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class MyUserDetails implements UserDetails {
private String username;
private String password;
private List<GrantedAuthority> grantedAuthorities;
public MyUserDetails(com.example.Uno.entity.User user){
this.username = user.getUsername();
this.password = user.getPassword();
for (Role r: user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority(r.getName()));
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return grantedAuthorities;
}
@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;
}
}
package com.example.Uno.repository;
import com.example.Uno.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import java.util.Optional;
@RepositoryRestResource
public interface UserRepository extends JpaRepository<User,Long> {
User findUserByUsername(String s);
}
package com.example.Uno.repository;
import com.example.Uno.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface RoleRepository extends JpaRepository<Role,Long> {
Role findRoleByName(String name);
}
package com.example.Uno.service;
import com.example.Uno.entity.MyUserDetails;
import com.example.Uno.entity.User;
import com.example.Uno.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findUserByUsername(s);
return new MyUserDetails(user);
}
}
package com.example.Uno.config;
import com.example.Uno.service.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.POST,"/users");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/users").hasRole("USER")
.anyRequest().permitAll().and().httpBasic();
}
}
User.java
package com.example.Uno;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootApplication
public class UnoApplication {
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
public static void main(String[] args) {
SpringApplication.run(UnoApplication.class, args);
}
}
package com.example.Uno.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
@Data
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@ManyToMany(mappedBy = "users",targetEntity = Role.class,cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.EAGER)
private Set<Role> roles = new HashSet<>();
}
package com.example.Uno.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
@Data
@Entity
public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.LAZY)
private Set<User> users = new HashSet<>();
}
package com.example.Uno.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class MyUserDetails implements UserDetails {
private String username;
private String password;
private List<GrantedAuthority> grantedAuthorities;
public MyUserDetails(com.example.Uno.entity.User user){
this.username = user.getUsername();
this.password = user.getPassword();
for (Role r: user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority(r.getName()));
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return grantedAuthorities;
}
@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;
}
}
package com.example.Uno.repository;
import com.example.Uno.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import java.util.Optional;
@RepositoryRestResource
public interface UserRepository extends JpaRepository<User,Long> {
User findUserByUsername(String s);
}
package com.example.Uno.repository;
import com.example.Uno.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface RoleRepository extends JpaRepository<Role,Long> {
Role findRoleByName(String name);
}
package com.example.Uno.service;
import com.example.Uno.entity.MyUserDetails;
import com.example.Uno.entity.User;
import com.example.Uno.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findUserByUsername(s);
return new MyUserDetails(user);
}
}
package com.example.Uno.config;
import com.example.Uno.service.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.POST,"/users");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/users").hasRole("USER")
.anyRequest().permitAll().and().httpBasic();
}
}
SecurityConfig.java
package com.example.Uno;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootApplication
public class UnoApplication {
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
public static void main(String[] args) {
SpringApplication.run(UnoApplication.class, args);
}
}
package com.example.Uno.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
@Data
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@ManyToMany(mappedBy = "users",targetEntity = Role.class,cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.EAGER)
private Set<Role> roles = new HashSet<>();
}
package com.example.Uno.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
@Data
@Entity
public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.LAZY)
private Set<User> users = new HashSet<>();
}
package com.example.Uno.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class MyUserDetails implements UserDetails {
private String username;
private String password;
private List<GrantedAuthority> grantedAuthorities;
public MyUserDetails(com.example.Uno.entity.User user){
this.username = user.getUsername();
this.password = user.getPassword();
for (Role r: user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority(r.getName()));
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return grantedAuthorities;
}
@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;
}
}
package com.example.Uno.repository;
import com.example.Uno.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import java.util.Optional;
@RepositoryRestResource
public interface UserRepository extends JpaRepository<User,Long> {
User findUserByUsername(String s);
}
package com.example.Uno.repository;
import com.example.Uno.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface RoleRepository extends JpaRepository<Role,Long> {
Role findRoleByName(String name);
}
package com.example.Uno.service;
import com.example.Uno.entity.MyUserDetails;
import com.example.Uno.entity.User;
import com.example.Uno.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findUserByUsername(s);
return new MyUserDetails(user);
}
}
package com.example.Uno.config;
import com.example.Uno.service.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.POST,"/users");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/users").hasRole("USER")
.anyRequest().permitAll().and().httpBasic();
}
}
谢谢你抽出时间
编辑
我在application.properties:logging.level.org.springframework.security=DEBUG中添加了这一行
当我发出上一个GET请求时,在后端看起来是这样的:
所以根据日志
com.example.Uno.entity.MyUserDetails@1c6f2612; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities'
您的用户详细信息没有任何权限,这意味着方法:findUserByUserName没有在用户对象中获取任何角色。或者,您需要使用另一个函数findRoleByName()单独查询出角色,并将其设置为userdetails
你的方向是正确的,离胜利很近 角色名称是:role\u USER?如果您可以从后端发布异常,它将帮助其他人调查…@bobtang是的角色名称是role\u USER,因为当我在数据库中添加角色时,我必须在其前面加上role\u。我在另一篇文章中发布了我的后端验证,因为我没有足够的空间添加到这里: