【问题标题】:@RolesAllowed in conjuction with configureGlobalSecurity jdbcAuthentication in Spring boot@RolesAllowed 与 Spring Boot 中的 configureGlobalSecurity jdbcAuthentication 结合使用
【发布时间】:2017-11-14 03:21:04
【问题描述】:

@RolesAllowed 在我使用jdbcAuthentication() 时似乎不起作用,但如果我使用inMemoryAuthentication(),它就可以正常工作。如果我删除 @RolesAllowedjdbcAuthentication() 工作正常。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.
            jdbcAuthentication()
            .usersByUsernameQuery("select u.email, u.password, u.enabled from bagtag.user u where email=?")
            .authoritiesByUsernameQuery("select u.email, r.name from bagtag.user u join bagtag.role r on (r.id = u.role_id) where u.email=?")
            .dataSource(dataSource)
            .passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().authorizeRequests().antMatchers("/api/**").fullyAuthenticated().and().httpBasic()
                .realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }
}

以下RequestMapping@RolesAllowed 一起使用,但如果我删除@RolesAllowed,它会起作用。我收到以下错误。

{
    "timestamp": 1510628906600,
    "status": 403,
    "error": "Forbidden",
    "exception": "org.springframework.security.access.AccessDeniedException",
    "message": "Access is denied",
    "path": "/api/user/admin"
} 

@RestController
@RequestMapping(value = "/api/user", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {

    @Autowired
    UserService us;

    @RolesAllowed(Role.SUPERADMIN)
    @RequestMapping(value = "/admin", method = RequestMethod.POST)
    public ResponseEntity<User> createAdmin(@RequestBody UserWrapper uw) {
       return new ResponseEntity<User>(uw.getUser(), HttpStatus.OK);
    }
}

我尝试使用以下命令检查经过身份验证的用户 System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());

返回

org.springframework.security.core.userdetails.User@ca3b1db5: Username: test@test.dk; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SUPERADMIN

我已尝试删除 @RolesAllowed 并替换以下行 http.csrf().disable().authorizeRequests().antMatchers("/api/**").fullyAuthenticated().and().httpBasic()

http.csrf().disable().authorizeRequests().antMatchers("/api/**").hasAnyRole(String.format("%s,%s,%s", Role.SUPERADMIN, Role.ADMIN, Role.STAFF)).and().httpBasic()

这给了我http status 403

{
    "timestamp": 1510629419006,
    "status": 403,
    "error": "Forbidden",
    "message": "Access is denied",
    "path": "/api/user/admin"
}

这是我数据库中的两个表。一个用户只能拥有一个角色。

CREATE TABLE `role` (
   `role_id` int(11) NOT NULL AUTO_INCREMENT,
   `role` varchar(255) DEFAULT NULL,
   `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`role_id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

CREATE TABLE `user` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `email` varchar(255) NOT NULL,
   `password` varchar(255) NOT NULL,
   `first_name` varchar(255) NOT NULL,
   `last_name` varchar(255) DEFAULT NULL,
   `role_id` int(11) NOT NULL,
   `enabled` bit(1) NOT NULL DEFAULT b'0',
   `last_login` timestamp NULL DEFAULT NULL,
   `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
   UNIQUE KEY `email_UNIQUE` (`email`),
 ) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8

【问题讨论】:

标签: java spring spring-boot jdbc spring-security


【解决方案1】:

所以我找到了解决问题的方法,我不得不将.rolePrefix("ROLE_"); 添加到我的configureGlobalSecurity 方法中。

我不确定为什么这是解决方案。根据文档,AuthenticationManagerBuilder 的默认角色前缀是空的 String。所以我最好的猜测是 Spring 默认角色前缀是“ROLE_”。

如果有人知道这种疯狂背后的真正解释,请发表评论或回答。非常感谢!

编辑: @RolesAllowed 默认前缀是 ROLE_ 这就是为什么你必须在 spring security 中添加 ROLE_ 前缀!

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
     public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
         auth.
            jdbcAuthentication()
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource)
            .passwordEncoder(bCryptPasswordEncoder)
            //.rolePrefix fixed the problem
            .rolePrefix("ROLE_");           
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().authorizeRequests().antMatchers("/api/**")
            .hasAnyRole(String.format("%s,%s,%s", Role.SUPERADMIN, Role.ADMIN, Role.STAFF)).and().httpBasic()
            .realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }
}

【讨论】:

  • 问题不是根据文档,AuthenticationManagerBuilder的默认角色前缀是一个空字符串。,问题是@RolesAllowed的默认值。
猜你喜欢
  • 2017-02-01
  • 2018-01-24
  • 2022-11-30
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
  • 2020-09-17
相关资源
最近更新 更多