@Configuration
@ComponentScan(basePackages={"com.api.security"})
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ApiAuthenticationProvider apiAuthenticationProvider;
@Autowired
private AuthTokenHeaderAuthenticationFilter authTokenHeaderAuthenticationFilter;
@Autowired
private AuthenticationEntryPoint apiAuthenticationEntryPoint;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(apiAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(authTokenHeaderAuthenticationFilter, BasicAuthenticationFilter.class) // Main auth filter
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests()
.antMatchers(HttpMethod.POST, "/v2/session").permitAll()
.anyRequest().authenticated();
http.exceptionHandling()
.authenticationEntryPoint(apiAuthenticationEntryPoint);
}
}
/**
* Main Auth Filter. Always sets Security Context if the Auth token Header is not empty
*/
@Component
public class AuthTokenHeaderAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
final String token = ((HttpServletRequest) request).getHeader(RequestHeaders.AUTH_TOKEN_HEADER);
if (StringUtils.isEmpty(token)) {
chain.doFilter(request, response);
return;
}
try {
AuthenticationToken authRequest = new AuthenticationToken(token);
SecurityContextHolder.getContext().setAuthentication(authRequest);
}
} catch (AuthenticationException failed) {
SecurityContextHolder.clearContext();
return;
}
chain.doFilter(request, response); // continue down the chain
}
}
自定义apiAuthenticationProvider将尝试基于标头中提供的令牌对所有请求进行身份验证,如果身份验证不成功,则抛出AccessException,客户端将收到HTTP 401响应:
@Component
public class ApiAuthenticationProvider implements AuthenticationProvider {
@Autowired
private remoteAuthService remoteAuthService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
AuthenticationToken authRequest = (AuthenticationToken) authentication;
String identity = null;
try {
identity = remoteAuthService.getUserIdentityFromToken(authRequest.getToken());
} catch (AccessException e) {
throw new InvalidAuthTokenException("Cannot get user identity from the token", e);
}
return new AuthenticationToken(identity, authRequest.getToken(), getGrantedAuthorites());
}
}
这对于需要身份验证的请求非常有效。对于没有身份验证标头的/v2/session请求,这很好。但是,对于/v2/session请求,如果在头部(或在cookie中--代码示例中没有显示;如果客户机没有清除头部或继续发送带有请求的cookie,有时可能会发生这种情况)中有一个过期的Auth令牌,则安全上下文将被初始化,apiAuthenticationProvider将抛出一个异常,并用HTTP 401响应客户机。
http.authorizeRequests()
.antMatchers(HttpMethod.POST, "/v2/session").permitAll()
我希望Spring Security性在调用apiauthenticationProvider.authenticate()之前确定这一点。对于配置为permitAll()的URL,过滤器或auth提供者应该如何忽略/不抛出异常?
在执行请求授权检查之前触发Spring Security过滤器。为了使授权检查发挥作用,假定请求已经通过过滤器,并且已经设置了Spring Security上下文(是否设置,取决于是否传入了身份验证凭据)。
在您的筛选器中,如果令牌不在,您可以检查是否继续进行筛选器链处理。不幸的是,如果它是,那么它将被传递给您的提供者进行身份验证,这将引发异常,因为令牌已经过期,因此您将获得401。
最好的办法是对您认为是公共的URL跳过筛选器执行。您既可以在筛选器本身中执行此操作,也可以在配置类中执行此操作。将以下方法添加到SecurityConfig
类中:
@Override
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers(HttpMethod.POST, "/v2/session");
}
这个问题看起来可能重复,但以下答案都没有解释何时使用: 和 HttpSecurity、WebSecurity和AuthenticationManagerBuilder Spring Security中Web忽略和Http允许的区别 通过阅读StackOverflow asnwers和几篇文章,我了解到: configure(HttpSecurity)允许在资源级别配置基于web的安全性。 conf
我试图使用资源令牌连接到Azure Cosmos DB中的Gremlin集合。我从这里修改了文档(主要针对C#):https://docs.microsoft.com/en-us/azure/cosmos-db/how-to-use-resource-tokens-gremlin 问题是,一旦我试图访问数据,令牌的日期标头似乎无效: 有人知道怎么解决吗?通过将JVM设置为GMT 连接并查询Grem
null 我目前拥有的是以下内容:当密码哈希和用户名在数据库中匹配时,刷新令牌endpoint生成一个JWT。每个刷新令牌都有一个存储在数据库中的jti,以及过期(仅用于DB清理)、device_id和一个revoked标志。可以使用refresh令牌命中另一个endpoint,该令牌返回一个JWT访问令牌。访问令牌的有效期为15分钟。无法吊销访问令牌。 我的问题出现在需求1上。我不希望用户在与网
我有一个带有JWT auth的Spring boot应用程序,非常好用!但我用无状态策略禁用了csrf: 这个Rest应用编程接口是为SPA反应应用程序设计的。我读到当我使用JWT令牌时,我不需要设置csrf令牌。JWT是否像csrf保护一样工作?我认为这不是csrf保护。
我试图做api-auth通过检查生成令牌从登录用户的用户名与md5加密方法在laravel 5.5飞,不想保存令牌到用户的表。当用户注销时,令牌将无效。URL将是这样的: http://myserver.com/products?token=...... 我该怎么做? 新增-这是第44届世界技能大赛的测试项目,以下为测试项目文件: 认证 A.登录(v1/auth/登录) 描述:供客户端通过用户名和
本文件规定: Firebase ID令牌是短暂的,只能持续一个小时;刷新令牌可用于检索新的ID令牌。 我是否可以说,刷新令牌本质上同时充当客户端设备的密码和标识,并且拥有刷新令牌意味着能够检索ID令牌,从而能够作为与该刷新令牌关联的用户进行身份验证? 如果是这样,那么拥有这两个不同的令牌的目的是什么? 谢谢