1

我从使用 Spring Security 的 JDBC 身份验证的 rest api 得到 403 Forbidden。

我已经使用带有 Spring boot 的 Jersey 编写了简单的 restful api,并尝试使用inMemoryAuthentication()方法实现 Spring Security,并且效果很好。但是当我切换到jdbcAuthentication()方法时,当我使用邮递员的有效凭据点击服务时,我会被禁止 403。我不明白我做错了什么。

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    DataSource dataSource; 

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.csrf().disable()
        .httpBasic()
        .and()
        .authorizeRequests()
        .antMatchers("/jersey/**").hasRole("USER")
        .antMatchers("/console/**").permitAll()
        .and()
        .headers().frameOptions().disable();
        //.anyRequest().permitAll();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.jdbcAuthentication().dataSource(dataSource)
        .authoritiesByUsernameQuery("select USERNAME, ROLE from EMPLOYEE where USERNAME=?")
        .usersByUsernameQuery("select USERNAME, PASSWORD , 1 as enabled from EMPLOYEE where USERNAME=?");
    }

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

data.sql

INSERT INTO EMPLOYEE VALUES ('lalit','$2a$10$TV//Fu/4UwMTIqnPbkahqeMNjrrF1YQT1MdEwNDvaHurH5wR7ZLnm','USER');

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

更新

error log:

2019-05-24 19:46:21.703 DEBUG 11724 --- [nio-8088-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f9c70a69: Principal: org.springframework.security.core.userdetails.User@61fa502: Username: lalit; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: USER
2019-05-24 19:46:21.706 DEBUG 11724 --- [nio-8088-exec-2] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@4a78101b, returned: -1
2019-05-24 19:46:21.713 DEBUG 11724 --- [nio-8088-exec-2] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is not anonymous); delegating to AccessDeniedHandler

org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
...

这就是当我使用有效凭据点击服务时得到的。

HTTP 状态 403 – 禁止

4

1 回答 1

1

你得到 403 Forbidden 因为 Spring Security 可能在数据库中找到了与角色“ROLE_USER”不同的角色,同时访问任何具有/jersey/.

也看看下面的配置。它可能是需要添加的密码编码器。

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

    auth.jdbcAuthentication()
            .dataSource(dataSource)
            .passwordEncoder(passwordEncoder())
            .authoritiesByUsernameQuery("select USERNAME, ROLE from EMPLOYEE where USERNAME=?")
            .usersByUsernameQuery("select USERNAME, PASSWORD , 1 as enabled from EMPLOYEE where USERNAME=?");
}

更新

将数据库中的角色保存为“ROLE_USER”而不是“USER”

由于您的错误日志显示凭据先前已通过身份验证,因此您需要在尝试再次登录之前删除浏览器的 cookie,或者只需打开一个新的隐身标签。

于 2019-05-24T10:06:03.547 回答