草庐IT

java - Spring自定义身份验证过滤器和提供者不调用 Controller 方法

coder 2024-03-13 原文

我正在尝试使用最新版本的 Spring Boot、Web 和 Security 实现自定义身份验证逻辑,但我遇到了一些问题。我在类似的问题/教程中尝试了许多解决方案,但没有成功,也没有理解实际发生的情况。

我正在创建一个具有无状态身份验证的 REST 应用程序,即有一个 REST 端点 (/web/auth/login) 需要用户名和密码并返回一个字符串 token ,然后在所有其他 REST 端点中使用它 (/api/**) 来识别用户。我需要实现自定义解决方案,因为将来身份验证会变得更加复杂,我想了解 Spring Security 的基础知识。

为了实现 token 身份验证,我正在创建自定义过滤器和提供程序:

过滤器:

public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

public TokenAuthenticationFilter() {
    super(new AntPathRequestMatcher("/api/**", "GET"));
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
    String token = request.getParameter("token");
    if (token == null || token.length() == 0) {
        throw new BadCredentialsException("Missing token");
    }

    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(token, null);

    return getAuthenticationManager().authenticate(authenticationToken);
}
}

提供商:

@Component
public class TokenAuthenticationProvider implements AuthenticationProvider {
@Autowired
private AuthenticationTokenManager tokenManager;

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String token = (String)authentication.getPrincipal();
    return tokenManager.getAuthenticationByToken(token);
}

@Override
public boolean supports(Class<?> authentication) {
    return UsernamePasswordAuthenticationToken.class.equals(authentication);
}
}

配置:

@EnableWebSecurity
@Order(1)
public class TokenAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private TokenAuthenticationProvider authProvider;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/api/**")
    .csrf().disable()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and().addFilterBefore(authenticationFilter(), BasicAuthenticationFilter.class);
}

@Bean
public TokenAuthenticationFilter authenticationFilter() throws Exception {
    TokenAuthenticationFilter tokenProcessingFilter = new TokenAuthenticationFilter();
    tokenProcessingFilter.setAuthenticationManager(authenticationManager());
    return tokenProcessingFilter;
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authProvider);
}
}

提供程序中使用的 AuthenticationTokenManager(以及登录过程中):

@Component
public class AuthenticationTokenManager {
private Map<String, AuthenticationToken> tokens;

public AuthenticationTokenManager() {
    tokens = new HashMap<>();
}

private String generateToken(AuthenticationToken authentication) {
    return UUID.randomUUID().toString();
}

public String addAuthentication(AuthenticationToken authentication) {
    String token = generateToken(authentication);
    tokens.put(token, authentication);
    return token;
}

public AuthenticationToken getAuthenticationByToken(String token) {
    return tokens.get(token);
}

会发生什么: 我在对“/api/bla”的请求中附加了一个有效 token (这是一个返回一些 Json 的 REST Controller )。过滤器和提供者都被调用。 问题是,浏览器被重定向到“/”而不是调用REST Controller 请求的方法。这似乎发生在 SavedRequestAwareAuthenticationSuccessHandler 中,但为什么要使用此处理程序?

我试过了

  • 实现一个空的成功处理程序,导致 200 状态代码并且仍然不调用 Controller
  • 在简单的 GenericFilterBean 中进行身份验证并通过 SecurityContextHolder.getContext().setAuthentication(authentication) 设置身份验证对象,这会导致出现“错误凭据”错误页面。

我想了解为什么在我验证 token 后我的 Controller 没有被调用。除此之外,是否有一种“Spring”方式来存储 token 而不是将其存储在 Map 中,就像 SecurityContextRepository 的自定义实现一样?

我真的很感激任何提示!

最佳答案

可能有点晚了,但我遇到了同样的问题并添加:

@Override
protected void successfulAuthentication(
        final HttpServletRequest request, final HttpServletResponse response,
        final FilterChain chain, final Authentication authResult)
        throws IOException, ServletException {
    chain.doFilter(request, response);
}

我的 AbstractAuthenticationProcessingFilter 实现成功了。

关于java - Spring自定义身份验证过滤器和提供者不调用 Controller 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38680694/

有关java - Spring自定义身份验证过滤器和提供者不调用 Controller 方法的更多相关文章

  1. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  2. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  7. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  8. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  9. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  10. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

随机推荐