2

我在使用 Spring Security 设置摘要身份验证时遇到问题:

我的安全配置:

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

{
    @Autowired
    private UserService userService;

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() {
        return userService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder registry) throws Exception {
        registry.userDetailsService(userDetailsServiceBean());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .exceptionHandling()
            .authenticationEntryPoint(digestEntryPoint())
        .and()
        .addFilterAfter(digestAuthenticationFilter(digestEntryPoint()), BasicAuthenticationFilter.class)
        .antMatcher("/**")
            .csrf()
            .disable()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
        .and()
            .formLogin()
            .permitAll()
        .and()
        .logout()
            .deleteCookies("remove")
            .invalidateHttpSession(true)
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login")
            .permitAll();
    }

    @Bean
    public DigestAuthenticationEntryPoint digestEntryPoint() {
        DigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new DigestAuthenticationEntryPoint();
        digestAuthenticationEntryPoint.setKey("acegi");
        digestAuthenticationEntryPoint.setRealmName("Digest Realm");
        digestAuthenticationEntryPoint.setNonceValiditySeconds(10);
        return digestAuthenticationEntryPoint;
    }

    @Bean
    public DigestAuthenticationFilter digestAuthenticationFilter(
            DigestAuthenticationEntryPoint digestAuthenticationEntryPoint) {
        DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
        digestAuthenticationFilter.setAuthenticationEntryPoint(digestEntryPoint());
        digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean());
        return digestAuthenticationFilter;
    }
}

使用以下用户服务:

@Component
public class UserService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("UserName " + username + " not found");
        } else {
            return user;
        }
    }

}

当尝试使用 Digest 访问 API 时,我得到以下返回:

{
  "timestamp": "2015-11-25T13:51:01.874+0000",
  "status": 401,
  "error": "Unauthorized",
  "message": "Nonce should have yielded two tokens but was ",
  "path": "/api/"
}

基本身份验证正在运行。文摘有什么问题?

使用 Postman 发送请求:

Digest username="admin", realm="Digest Realm", nonce="", uri="/api/", response="762b17f23b0e1a2d56cd159805732d7b", opaque=""
4

1 回答 1

2

您需要设置一个 nonce 值。错误是 BadCredentialsException,快速查看您发送的内容表明您已设置 nonce=""。这应该是格式 -

base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))

            expirationTime:   The date and time when the nonce expires, expressed in milliseconds
            key:              A private key to prevent modification of the nonce token

https://docs.spring.io/spring-security/site/docs/3.0.x/reference/basic.html

于 2015-11-25T14:25:43.120 回答