簡體   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