当前位置: 首页 > 面试题库 >

Spring Security-在REST服务中将凭证作为JSON而不是常规格式发送

章永安
2023-03-14
问题内容

我正在rest与一起写服务json。对于后端,我使用Spring Security。我有形式巫婆发送与ajax rest对象,如下所示:

{email: "admin", password: "secret"}

现在在服务器上,我的配置如下:

@Configuration
@EnableWebSecurity
@ComponentScan("pl.korbeldaniel.cms.server")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
    @Autowired
    private RestAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private RestAuthenticationFailureHandler authenticationFailureHandler;

    @Bean
    JsonAuthenticationFilter jsonAuthenticationFilter() throws Exception {
    JsonAuthenticationFilter filter = new JsonAuthenticationFilter();
    filter.setAuthenticationManager(authenticationManagerBean());
    System.out.println("jsonAuthenticationFilter");
    return filter;
    }

    @Bean
    public RestAuthenticationSuccessHandler mySuccessHandler() {
    return new RestAuthenticationSuccessHandler();
    }

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("admin").password("secret").roles("ADMIN");
    // auth.jdbcAuthentication().
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(jsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    http.csrf().disable();//
    http.exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint)//
        .and().authorizeRequests()//
        .antMatchers("/").permitAll()//
        .antMatchers("/services/anonymous/**").permitAll()//
        .antMatchers("/services/authenticated/**").authenticated()//
        .and().formLogin().loginProcessingUrl("/services/anonymous/loginService/login").usernameParameter("email").passwordParameter("password")//
        .successHandler(authenticationSuccessHandler)//
        .and().logout().logoutUrl("/services/anonymous/loginService/logout");
    // http.httpBasic();
    }
}

问题是春季安全要求我发送凭据作为正文,但是我想春季接受我的Json对象。

因此,我基于此编写了自己的身份验证过滤器:

@Component
public class JsonAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private boolean postOnly;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    System.out.println("attemptAuthentication");
    if (postOnly && !request.getMethod().equals("POST")) {
        throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
    }

    UsernamePasswordAuthenticationToken authRequest = this.getUserNamePasswordAuthenticationToken(request);

    // Allow subclasses to set the "details" property
    setDetails(request, authRequest);

    return this.getAuthenticationManager().authenticate(authRequest);
    }

    /**
     * @param request
     * @return
     */
    private UsernamePasswordAuthenticationToken getUserNamePasswordAuthenticationToken(HttpServletRequest request) {
    // TODO Auto-generated method stub
    System.out.println(request);
    return null;
    }

}

但是不幸的是,这个过滤器似乎不起作用。

当我从登录表单发送ajax发布请求时,我得到了302 Found,然后得到了:

Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/cms/login?error
Request Method:GET
Status Code:404 Not Found

就像那里没有验证用户凭据(因为表单主体为空,并且凭据作为json)一样,然后将其重定向到login?error不存在的原因,因为我有自己的登录表单。

请帮忙。

编辑

public class WebServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] { SecurityConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
    // return new String[] { "/" };
    // return new String[] { "/cms/" };
    return new String[] { "/services/*" };
    }
}


@EnableWebMvc
@ComponentScan(basePackages = "pl.daniel.cms.server")
public class WebConfig extends WebMvcConfigurerAdapter {
}

问题答案:

好吧,除非您编写 getUserNamePasswordAuthenticationToken 主体,否则它一定不能起作用。

实际上,您必须阅读HttpServletRequest的请求正文,通过Jackson或其他任何映射方式对其进行解析,并使用它创建UsernamePasswordAuthenticationToken。

使用Jackson(根据您的Spring版本选择正确的版本),我将创建一个像这样的简单bean:

@JsonIgnoreProperties(ignoreUnkown=true)
    public LoginRequest{
     private String email;
     private String password;
     // getters & setters
    }

使用它来映射它的请求主体:

private UsernamePasswordAuthenticationToken getUserNamePasswordAuthenticationToken(HttpServletRequest request)  throws IOException{
    StringBuffer sb = new StringBuffer();
    BufferedReader bufferedReader = null;
    String content = "";
    LoginRequest sr = null;

    try {
        bufferedReader =  request.getReader()
        char[] charBuffer = new char[128];
        int bytesRead;
        while ( (bytesRead = bufferedReader.read(charBuffer)) != -1 ) {
            sb.append(charBuffer, 0, bytesRead);
        }
        content = sb.toString();
        ObjectMapper objectMapper = new ObjectMapper();
        try{
            sr = objectMapper.readValue(content, LoginRequest.class);
        }catch(Throwable t){
            throw new IOException(t.getMessage(), t);
        }
    } catch (IOException ex) {

        throw ex;
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                throw ex;
            }
        }
    }
    return new UsernamePasswordAuthenticationToken(sr.getEmail(), sr.getPassword());

}

PD Yo必须使用Post,否则您将永远无法使用GET发布请求正文



 类似资料:
  • 从rest服务抛出的异常以某种方式返回为JSON是否可能?我有一个JAX-RS Rest服务来实现这一点。当我现在抛出它时,它被映射到一个HTML响应,这不是我想要的。据我所知,ExceptionMapper也会将其映射到HTML?是否有其他可供选择的或库允许以JSON格式返回异常?

  • 环境:Java,泽西,jackson,汤卡特。 我有一个rest服务从客户端获取JSON输入。我想验证输入,如果它是JSON,然后它是JSON,然后JSON输入中的键是预期的或不是。如果是,那么它将产生HTTP400-bad请求。 比如-- 例如-非json输入如 null 我的代码适用于前面提到的情况2,但我希望它也适用于情况1。当非JSON输入存在时,我希望它将凭据对象设置为null,然后我可

  • 我有一个方法返回。代码如下类所示: 和作为错误。 如何解决此错误

  • 问题内容: 我正在使用jQuery将JSON发布到Java服务器,但是我认为JSON一定是错误的。这是我的数据及其发送方式的示例: 我正在使用Wicket的AbstractAjaxBehavior接收数据,并希望获得一个我可以解析的JSON字符串。当我获得传递的参数的映射时,键集如下所示: 显然,我可以轻松获取名称和描述的值,但是我的项目数组的键弄乱了。我敢肯定这很简单,但是我似乎一直在解决这个问

  • 我正在探索Spring数据REST库以构建RESTAPI。 但在许多示例中,我看到RESTAPI是从Crudepository生成的。 我想知道这在生产中是否真的有用?在我看来,快速启动和运行某些东西很容易,但我宁愿将RESTAPI与“真正的”服务相结合,而不是“仅仅”与存储库相结合。 你对此有何看法? 亲切的问候B

  • 最近我被扫描指纹卡住了。经过大量的谷歌搜索,我得出结论,手指打印不能在Marshmallow或Android更大版本中使用。 还有一件事我得出结论,当你们用内置传感器扫描指纹图像时,你们不能将指纹图像存储到像MYSQL这样的外部服务器(通过web服务)。 所以,任何人都知道我如何存储指纹并在我的应用程序中使用它来验证用户身份。 提前谢谢。