如何使用 Spring Security 模拟身份验证和授权
Posted
技术标签:
【中文标题】如何使用 Spring Security 模拟身份验证和授权【英文标题】:How to mock authentication and authorization with Spring Security 【发布时间】:2020-03-15 08:10:10 【问题描述】:我有一个 spring-boot REST API 应用程序。 REST 端点受 spring-security 保护。
这是spring-security的配置:
protected void configure(HttpSecurity httpSecurity) throws Exception
httpSecurity
.exceptionHandling().authenticationEntryPoint(new CustomForbiddenErrorHandler())
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/api/**").authenticated() // HTTP 403 if the request is not authenticated
.antMatchers("/**").permitAll();
它工作正常。如果我在 HTTP 标头上没有授权令牌的情况下进行休息调用,我会返回正确的 HTTP 错误代码。
如果没有按顺序显示,我可以强制 spring 以某种方式添加一个自我身份验证令牌,这样我就可以在没有自己的访问管理系统的情况下进行 REST 调用吗?稍后安装。
我不是在问如何编写 JUnit 测试。我要问的是如何动态生成模拟身份验证令牌,如果不存在则将其添加到请求中。
【问题讨论】:
Spring Test & Security: How to mock authentication?的可能重复 【参考方案1】:您可以覆盖现有的身份验证过滤器,或创建新的自定义过滤器,以检查请求是否包含不记名令牌。根据结果,您可以按原样处理请求,也可以使用您的自定义身份验证对象扩充请求。
查看OAuth2AuthenticationProcessingFilter,这会从传入请求中提取 OAuth2 令牌并使用它来填充 Spring Security 上下文。您可以覆盖其行为或创建一个新过滤器,使用您的模拟身份验证对象填充安全上下文。
下面是一个示例代码,可帮助您入门:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
boolean debug = logger.isDebugEnabled();
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
try
Authentication authentication = this.tokenExtractor.extract(request);
if (Objects.isNull(authentication))
final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken("username", "password");
authenticationToken.setDetails(Collections.singletonMap("user_uuid", userUuid.toString()));
final OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(null, authenticationToken);
// You can either ask your authenticatoin manager to authenticate these credentials or directly publish auth success event with your mock auth object.
this.eventPublisher.publishAuthenticationSuccess(oAuth2Authentication);
SecurityContextHolder.getContext().setAuthentication(oAuth2Authentication);
else
request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, authentication.getPrincipal());
if (authentication instanceof AbstractAuthenticationToken)
AbstractAuthenticationToken needsDetails = (AbstractAuthenticationToken)authentication;
needsDetails.setDetails(this.authenticationDetailsSource.buildDetails(request));
Authentication authResult = this.authenticationManager.authenticate(authentication);
if (debug)
logger.debug("Authentication success: " + authResult);
this.eventPublisher.publishAuthenticationSuccess(authResult);
SecurityContextHolder.getContext().setAuthentication(authResult);
【讨论】:
以上是关于如何使用 Spring Security 模拟身份验证和授权的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Security 中将令牌转换为身份验证?
如何在 Spring Security 中使用 LDAP 身份验证创建令牌
如何使用spring security使用空密码进行基本身份验证?
如何在同一应用程序中使用 spring-sample 示例配置 Spring Security 基本身份验证和 SAML 身份验证