【发布时间】:2020-08-06 12:04:06
【问题描述】:
我有一套规则,它规定哪些角色可以访问哪个网址。但是,我在角色应该有权访问的 url 上得到 403。代码和问题请参考下面
日志
org.springframework.security.access.AccessDeniedException: 访问是 拒绝于 org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE] 在 org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE] 在 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123) ~[spring-security-web-5.3.3.RELEASE.jar:5.3.3.RELEASE]
Spring 安全配置。注意 admin/** 允许管理员使用。我已经用 admin 登录,进入 admin/welcome,它给了我 403。
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
// To access the h2 embedded database
@Autowired
DataSource dataSource;
@Autowired
Securityhandler successHandler;
@Autowired
public void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication()
// To find logins in the h2 database
.dataSource(dataSource)
.usersByUsernameQuery("select email, password, 'true' as enabled from User where email = ?")
.authoritiesByUsernameQuery("select email, role " +
"from User " +
"where email =?");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/*", "/h2-console/**").permitAll()
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/admin/**").hasRole("ADMIN")
// formLogin redirect to login page
.and().formLogin()
.successHandler(successHandler);
// In order to work with spring security csrf protection needs to be disabled
http.csrf().disable();
http.headers().frameOptions().disable();
}
// To encrypt password
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
使用 commandlinerunner 创建的管理员用户,因此它是在运行应用程序时自动创建的。注意最后的管理员角色
@Override
public void run(String... args) throws Exception {
// Creates new user upon running the app
String password = securityConfig.passwordEncoder().encode("github");
User user = new User("Billy", "billy", password, password, "sof@gmail.com", "ADMIN");
userRep.save(user);
System.out.println("Saved user:" + user);
}
实体类
@Entity
@ValidPassword
public class User {
@Pattern(regexp="[a-zA-Z]+", message = "Enter letters only!")
private String firstName;
@Pattern(regexp="[a-zA-Z]+", message = "Enter letters only!")
private String lastName;
private String password;
private String matchingPassword;
private String passportNumber;
private String address;
private String phoneNumber;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@ValidEmail
private String email;
// Mark as primary key
@Id
// Will be auto generated
@GeneratedValue
private long id;
private String role;
public User(String firstName, String lastName, String password, String passportNumber, String address,
String phoneNumber, String email, String role) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
this.passportNumber = passportNumber;
this.address = address;
this.phoneNumber = phoneNumber;
this.email = email;
this.role = role;
}
@Override
public String toString() {
return "User [firstName=" + firstName + ", lastName=" + lastName + ", password=" + password
+ ", matchingPassword=" + matchingPassword + ", passportNumber=" + passportNumber + ", address="
+ address + ", phoneNumber=" + phoneNumber + ", email=" + email + ", id=" + id + ", role=" + role + "]";
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMatchingPassword() {
return matchingPassword;
}
public void setMatchingPassword(String matchingPassword) {
this.matchingPassword = matchingPassword;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPassportNumber() {
return passportNumber;
}
public void setPassportNumber(String passportNumber) {
this.passportNumber = passportNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setId(long id) {
this.id = id;
}
public User() {
}
public User(String firstName, String lastName, String password, String matchingPassword, String email,
String role) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.matchingPassword = matchingPassword;
this.password = password;
this.email = email;
this.role = role;
}
public long getId() {
return id;
}
【问题讨论】:
-
从
SecurityContextHolder.getContext().getAuthentication().getAuthorities()调试您的权限并检查角色名称是否不同(以ROLE_为前缀)?
标签: java spring spring-boot spring-mvc spring-security