【发布时间】:2015-01-27 16:36:43
【问题描述】:
我有一个玩具网络应用程序,我想在其中登录从数据库中获取的用户。
它可以工作,但是我可以使用 USER 角色登录,而我应该只使用具有 ADMIN 角色的用户登录。
这是我的代码:
Servlet 3.0 引导程序
public class Bootstraper extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{JPAConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{MvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected Filter[] getServletFilters() {
return new Filter[]{new DelegatingFilterProxy("springSecurityFilterChain"), new OpenEntityManagerInViewFilter()};
}
}
用户实体:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true)
private String name;
@Column
private String password;
@Column
private boolean enabled;
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
private Set<Role> roles = new HashSet<>();
public User() {
}
public User(String name, String password, boolean enabled) {
this.name = name;
this.password = password;
this.enabled = enabled;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
", enabled=" + enabled +
'}';
}
}
角色实体:
@Entity
@Table(name = "roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String role;
@JoinColumn(name = "u_id")
@ManyToOne
private User user;
public Role() {
}
public Role(String role) {
this.role = role;
}
public Long getId() {
return id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", role='" + role + '\'' +
", user=" + user +
'}';
}
}
我的客户用户详情服务:
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UsersService usersService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = usersService.getUser(username);
if (user != null) {
List<GrantedAuthority> authorityList = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getRole()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(username, user.getPassword(), user.isEnabled(), true, true, true, authorityList);
}
return null;
}
}
我将我的角色保留在数据库中,作为字符串:USER、MODERATOR、ADMIN
我的 Spring 安全配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.antMatchers("/**").access("hasRole('ROLE_ADMIN')")
.and().formLogin()
.loginPage("/login")
.permitAll().and()
.logout().permitAll();
http.csrf().disable();
}
}
问题是伙计们,我说过我希望每个用户都拥有 ROLE_ADMIN 但我仍然可以使用只有 USER 角色的用户登录。我不明白为什么。
我已经调试过了,我的用户从数据库中成功获取,一切都很好,但我不知道Spring在哪里检查角色。
问候,
【问题讨论】:
-
启用调试日志(log4j.logger.org.springframework.security=DEBUG, stdout, fileout - for log4j)它会告诉你很多。
-
请把
ROLE_ADMIN改成ADMIN试试看。 -
@Mithun 访问功能不需要“ROLE_”。见docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/…
-
@Evgeni - 感谢您的纠正。
标签: java spring security login