使用 REST 和 Javaconfig 在 Spring Security 中摘要 Auth

Posted

技术标签:

【中文标题】使用 REST 和 Javaconfig 在 Spring Security 中摘要 Auth【英文标题】:Digest Auth in Spring Security with REST and Javaconfig 【发布时间】:2015-11-25 13:59:10 【问题描述】:

我在使用 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=""

【问题讨论】:

【参考方案1】:

您需要设置一个 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

【讨论】:

谢谢。忘记添加从服务器返回的随机数!

以上是关于使用 REST 和 Javaconfig 在 Spring Security 中摘要 Auth的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Security 和 Angularjs 保护 Spring Rest 服务?

让 oauth2 与 spring-boot 和 rest 一起工作

Spring JavaConfig实例

Spring重温--Spring JavaConfig

如何快速构建基于Spring4.0的Rest API

为啥@JavaConfig 在 Spring MVC 中不起作用?