英文:
Spring Boot AuthenticationToken with path variable
问题
我有一个带有自定义AuthenticationManager的PreAuthenticatedProcessingFilter,在其中进行身份验证并创建AuthenticationToken。现在我需要访问路径变量(例如“/foo/{id}”的id),并将其用于我的身份验证。如何访问这个变量?如果我使用`.antMatchers("/foo/{id}").access("@demo.check(authentication,#id)");`,例如,我无法创建自己的令牌。
我目前的代码是:
MyAuthFilter filter = MyAuthFilter();
filter.setAuthenticationManager(new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// ... 身份验证内容
// 这里我想访问路径变量
return new MyAuthenticationToken(foo);
}
});
httpSecurity.antMatcher("/foo/**").csrf().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilter(filter).authorizeRequests().anyRequest().authenticated();
# 更新
我现在在访问表达式内部检查所有内容(您可以在那里访问HttpServletRequest,并将路径变量作为参数)。我不想在控制器中拥有逻辑或检查原始路径。所以对我来说,现在这个工作得很好:
httpSecurity.antMatcher("/foo/**").csrf().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
.antMatchers("/foo/test/{testId}/**")
.access("@fooApiGuard.check(authentication, #testId);");
@Service
public class FooApiGuard {
@Autowired
private HttpServletRequest request;
public boolean check(Authentication authentication, Long testId) throws AuthenticationException {
// 检查内容
return true;
}
}
英文:
i have a PreAuthenticatedProcessingFilter
with a custom AuthenticationManager
where i do my authentication and create a AuthenticationToken
. I now need to access a path variable (eg. id of "/foo/{id}") and use that for my authentication. How can i access the variable? If i use .antMatchers("/foo/{id}").access("@demo.check(authentication,#id)");
for example i cant create my own token.
my current code is:
MyAuthFilter filter = MyAuthFilter();
filter.setAuthenticationManager(new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// ... authentication stuff
// here i want to access the path variable
return new MyAuthenticationToken(foo);
}
});
httpSecurity.antMatcher("/foo/**").csrf().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilter(filter).authorizeRequests().anyRequest().authenticated();
Update
i am now checking everything inside the access expression (you can access the HttpServletRequest there and have the path variables as parameter). I did not want to have logic in the controller or check the raw path. So this works fine for me now:
httpSecurity.antMatcher("/foo/**").csrf().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
.antMatchers("/foo/test/{testId}/**")
.access("@fooApiGuard.check(authentication, #testId)");
@Service
public class FooApiGuard {
@Autowired
private HttpServletRequest request;
public boolean check(Authentication authentication, Long testId) throws AuthenticationException {
// check stuff
return true;
}
}
答案1
得分: 1
Spring Security是构建为过滤器链的,这意味着在您的自定义过滤器或AuthenticationManager
内部,与控制器方法本身的上下文不完全相同。事实上,您的自定义过滤器应该增强稍后由控制器使用的上下文。
您可以访问的是ServletRequest
和ServletResponse
对象,因此如果必要,您可以从中提取原始路径。然而,这并不能让您得到很好分离的请求参数。
如果路径参数仅用于确定是否已授权,则您可以简化身份验证逻辑,然后随后通过附加安全检查来增强控制器,以验证例如域级安全性问题(资源是否属于当前用户)。
英文:
Spring Security is built as a Filter chain, which means that inside your custom filter or AuthenticationManager
you do not have quite the same context as inside the controller method itself. In fact, your custom filter is supposed to augment the context which will be used down the line by your controller.
What you do have access to is the ServletRequest
and ServletResponse
objects, so if you must you could extract the raw path from that. However, that doesn't give you the nicely separated out request parameter.
If the path parameter is only necessary to determine whether or not someone is authorized then you could simplify your authentication logic and then subsequently augment your controller with additional security checks to validate e.g. domain level security concerns (does the resource belong to the current user).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论