用户角色是从db检索的,但是@PreAuthorize使用Basic Auth忽略了它,我得到了HTTP 403

时间:2015-12-03 00:28:51

标签: spring-security

我正在使用Spring security 4.0.3开发一个REST应用程序,我使用Postman使用Basic Auth发送请求。我填充了我的db表用户和角色。我已经覆盖了执行的loadUserByUsername,并在使用Basic auth时正确检索用户及其角色。

  • 我总是得到HTTP 403 - 访问被拒绝
  • REST请求将始终包含Basic Auth
  • 我尝试使用SecurityConfig.configure()上的几个配置但没有成功
  • 带注释的方法永远不会被执行

我能错过什么?

这些是我的文件:

AuthService

@Service
public class AuthService implements UserDetailsService {
    @Autowired
    private UserDAO userDAO;

    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        UserVO vo = userDAO.getUserByUsername(new UserVO(username)).get();
        System.out.println("User role: " + vo.getRole()); //The user role is printed successfully
        GrantedAuthority authority = new SimpleGrantedAuthority(vo.getRole());
        UserDetails userDetails = (UserDetails)new User(vo.getUsername(), vo.getPassword(), Arrays.asList(authority));
        return userDetails;
    }
}

AppConfig

@Configuration
@EnableWebMvc
@ComponentScan( basePackages = "com.nemesis" )
@Import({ SecurityConfig.class })
public class AppConfig {

    @Bean 
    public UserService userService() {
        return new UserServiceImpl();
    }

    @Bean
    public DataSource  dataSource() {
        return new DriverManagerDataSource("jdbc:mysql://127.0.0.1:3307/nemesis", "root", "");
    }   

    @Bean
    public UserDAO userDAO() {
        UserDAO userDAO = new UserDAOImpl();
        userDAO.setDataSource(dataSource());
        return userDAO;
    }
}

SecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthService authService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(authService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .httpBasic()
        .and().authorizeRequests()
        //.antMatchers("/**").access("hasRole('USER')"); //I tried with this also, no success
        .antMatchers("/**").permitAll();
    }   
}

UserController

@RestController
public class UserController {

    @Autowired
    UserService userService;

    @RequestMapping(value = "/user/{username}", method = RequestMethod.GET, produces = "application/json" )
    public ResponseEntity<UserVO> getUser(@PathVariable String username) throws Exception {
        return userService.getUser(username);

    }
}

UserService(具有带注释的方法)

public interface UserService {
    @PreAuthorize("hasAnyRole('ADMIN')")
    ResponseEntity<UserVO> getUser(String username);
}

UserServiceImpl

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDAO userDAO;

    @Override
    public ResponseEntity<UserVO> getUser(String username) {
        return new ResponseEntity<UserVO>(userDAO.getUserByUsername(new UserVO(username)).orElseThrow(() -> new CustomUserNotFoundException()), HttpStatus.OK);
    }   
}

的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>Nemesis</display-name>


  <context-param>
      <param-name>contextClass</param-name>
      <param-value>
         org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
   </context-param>
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.nemesis.config</param-value>
   </context-param>

    <filter>
       <filter-name>springSecurityFilterChain</filter-name>
       <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>springSecurityFilterChain</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>  

   <servlet>
      <servlet-name>rest</servlet-name>
      <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <init-param>
         <param-name>contextClass</param-name>
         <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
         </param-value>
      </init-param>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>com.nemesis.config</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>rest</servlet-name>
      <url-pattern>/rest/*</url-pattern>
   </servlet-mapping>

</web-app>

我发送的请求是这样的:

Postman request with basic auth

1 个答案:

答案 0 :(得分:0)

一切都很好,唯一的问题是我没有在注释中添加前缀“ROLE_”以及数据库,而不是ADMIN我改为ROLE_ADMIN,这就是全部。