java - Spring、@RolesAllowed 和数据库来保护页面

标签 java spring spring-security

我的数据库中有两个表格。用户和 user_role。

CREATE TABLE `user` (
  `username` varchar(50) NOT NULL,
  `password` varchar(255) NOT NULL,
  `enable` tinyint(4) NOT NULL DEFAULT '1',
  PRIMARY KEY (`username`),
  UNIQUE KEY `unique_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE `user_roles` (
  `user_role_id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) NOT NULL,
  `ROLE` varchar(45) NOT NULL,
  PRIMARY KEY (`user_role_id`),
  UNIQUE KEY `uni_username_role` (`ROLE`,`username`),
  KEY `fk_username_idx` (`username`),
  CONSTRAINT `fk_username` FOREIGN KEY (`username`) REFERENCES `user` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

user_roles 中的“ROLE”显示用户拥有的角色{ROLE_USER, ROLE_ADMIN}

我想使用 @RolesAllowed 拒绝用户访问某些页面(并授予管理员访问权限),但我不知道如何从数据库获取 user_role 并将其发送到 RolesAllowed。

在Controller中获取user_role不是问题,但我认为在每个函数中检查用户角色不是一个好主意。

或者,也许有比使用 @RolesAllowed 更好的解决方案?

抱歉问了个愚蠢的问题,这已经是我第一次看到 Spring 的 5 个小时了。

最佳答案

您没有提供有关您正在构建的应用程序的体系结构的详细信息,但作为初学者,我可以为您提供我当前正在构建的应用程序的一些示例。我正在使用 Spring Boot、JPA、Spring Data 和 Spring Security。我有类似的需求并这样解决:

我已经实现了 UserDetailsS​​ervice 接口(interface)。它用于检索有关尝试登录的用户的信息。当我使用 JPA 和 Spring Data 时,服务和模型类看起来像这样(为了简洁起见,删除了 getter、setter 和大多数字段):

@Entity
// in your case this would map to the User table
public class Profile implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    // you should probably use bean validation / jpa to assure uniqueness etc.
    private String name;
    ...

    @ElementCollection(fetch = FetchType.EAGER)
    private Set<Role> roles = ImmutableSet.<Role> of(new Role("USER"));
    ...
}

@Embeddable
// in your case this would map to the user_role table
public class Role implements GrantedAuthority {

    public final static Role USER = new Role("USER");
    public final static Role ADMIN = new Role("ADMIN");

    private String authority;

    ...

}

@Transactional
@Service
public class ProfileService implements UserDetailsService {

    private final ProfileRepository profileRepository;

    @Autowired
    public ProfileService(ProfileRepository profileRepository){
            this.profileRepository = profileRepository;
    }

    public Profile loadUserByUsername(String username) throws UsernameNotFoundException {
        Profile profile = profileRepository.findByUsername(username);

        // this is the only way to authenticate
        if (profile == null) {
            throw new UsernameNotFoundException("security.userNotFound");
        }

        return profile;
    }

// you may want to add profile creation etc.
...
}

完成此设置后,我必须配置 Spring Security 才能使用此服务。我主要使用 Java Config,所以配置看起来像这样。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private ProfileService profileService;

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

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/**")
                .authenticated()
                ...
                // you may want to put more config here
      }
}

关于java - Spring、@RolesAllowed 和数据库来保护页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28257098/

相关文章:

java - Ajax调用数据不绑定(bind)

spring mvc addAttribute到模型,如何从jsp javascript中获取它

java - 如何使用 Spring 安全性和 Restful Web 服务验证数据库中的凭据?

java - 如何使用 Spring Security 允许所有请求?

java - 无法将 DaoAuthenticationConfigurer 应用于已构建的对象

java - 即使 .class 文件存在,也会出现 java.lang.NoClassDefFoundError 错误

java - HessianConnectionException : (HTTP) 500 error when using Hessian 4. 0.7 和 Spring 3.1.1

java - 如何从 Web 服务向 Android 客户端发送消息?

spring - Spring Security如何在Grails中调用remoteFunction时重定向到登录

java - 使 MessageBodyWriter 不消耗资源类并返回资源一中的子资源类