使用 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 服务?