繁体   English   中英

在Spring Boot中与configureGlobalSecurity jdbcAuthentication结合使用@Roles

[英]@RolesAllowed in conjuction with configureGlobalSecurity jdbcAuthentication in Spring boot

@RolesAllowed似乎不工作时使用IM 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但是如果我删除@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());检查经过身份验证的用户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

因此,我找到了解决问题的方法,我必须添加.rolePrefix("ROLE_"); 到我的configureGlobalSecurity方法。

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

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

编辑: @RolesAllowed默认前缀是ROLE_ ,这就是为什么必须为弹簧安全性添加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);

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM