我正在尝试在我使用Spring Boot开发的rest api上实现无状态基于令牌的身份验证.我们的想法是客户端包含带有任何请求的JWT令牌,过滤器从请求中提取此令牌,并根据令牌的内容设置SecurityContext与相关的Authentication对象.然后,该请求将照常路由,并使用映射方法上的@PreAuthorize进行保护.
我的安全配置如下:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JWTTokenAuthenticationService authenticationService;
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.csrf().disable()
.headers().addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
.and()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.addFilterBefore(new StatelessAuthenticationFilter(authenticationService), UsernamePasswordAuthenticationFilter.class);
}
Run Code Online (Sandbox Code Playgroud)
使用无状态过滤器扩展GenericFilterBean,定义如下:
public class StatelessAuthenticationFilter extends GenericFilterBean {
private static Logger logger = Logger.getLogger(StatelessAuthenticationFilter.class);
private JWTTokenAuthenticationService authenticationservice;
public StatelessAuthenticationFilter(JWTTokenAuthenticationService authenticationService)
{
this.authenticationservice = authenticationService;
}
@Override
public void doFilter( ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest …
Run Code Online (Sandbox Code Playgroud) 我开发了一个使用基于令牌的身份验证的无状态REST API,我通过SecurityContextHolder.getContext().setAuthentication(authentication)
在自定义安全过滤器中调用,手动将Authentication对象添加到安全上下文.我一直遇到上下文没有正确设置的问题,我认为是由于这个原因:
在单个会话中接收并发请求的应用程序中,将在线程之间共享相同的SecurityContext实例.即使正在使用ThreadLocal,它也是从HttpSession为每个线程检索的相同实例.如果您希望临时更改运行线程的上下文,则会产生影响.如果您只使用SecurityContextHolder.getContext(),并对返回的上下文对象调用setAuthentication(anAuthentication),则Authentication对象将在共享同一SecurityContext实例的所有并发线程中更改....
您可以自定义SecurityContextPersistenceFilter的行为,为每个请求创建一个全新的SecurityContext,防止一个线程中的更改影响另一个线程.
所以问题是 - 你如何改变SecurityContextPersistenceFilter的行为?
我希望安全上下文不与http会话相关联,但不希望将会话创建策略设置为无状态,因为我仍然希望实现CSRF保护等.
multithreading spring-security security-context servlet-filters spring-boot
在使用Spring Boot编写的rest API上使用基于无状态令牌的身份验证时,我看到一些奇怪的行为。
客户端在每个请求中都包含一个JWT令牌,我编写的自定义过滤器扩展了GenericFilterBean,它使用以下内容基于令牌中的声明向安全上下文添加了Authentication对象:
SecurityContextHolder.getContext().setAuthentication(authentication);
Run Code Online (Sandbox Code Playgroud)
并通过执行以下操作来清除上下文:
SecurityContextHolder.getContext().setAuthentication(null);
Run Code Online (Sandbox Code Playgroud)
但是,当我开发的简单应用执行一系列操作时,有时会看到安全上下文设置不正确-有时对于提供令牌的请求而言,它为null。正确地调用了过滤器,还调用了setAuthencation(),但是请求未通过身份验证,并抛出403被拒绝。
如果我通过将会话创建策略设置为STATELESS来明确关闭任何http会话管理,则此行为将停止。
有什么想法会在这里发生吗?安全上下文是否以某种方式在处理请求的线程之间共享?
authentication spring-security thread-safety security-context spring-boot
我正在使用适用于Java的eBay Finding API,并根据随附的教程执行基本的测试搜索。调用完成,但是java.lang.IllegalArgumentException
在执行过程中引发异常。
这是从示例改编的基本代码:
ClientConfig config = new ClientConfig();
config.setEndPointAddress("http://svcs.ebay.com/services/search/FindingService/v1");
config.setGlobalId("EBAY-GB");
config.setApplicationId("my app id");
FindingServicePortType serviceClient =FindingServiceClientFactory.getServiceClient(config);
FindItemsByKeywordsRequest request = new FindItemsByKeywordsRequest();
request.setKeywords("HTC One X");
FindItemsByKeywordsResponse result = serviceClient.findItemsByKeywords(request);
System.out.println("Ack = "+result.getAck());
Run Code Online (Sandbox Code Playgroud)
这是记录的输出:
[ERROR] 2012-11-01 16:52:09,847
fail to get xml string from SOAP message
java.lang.IllegalArgumentException: Not supported: indent-number
Run Code Online (Sandbox Code Playgroud)
有没有其他人经历过这个/不知道为什么?