Отображение JSONObject в Rest Template для получения аутентификации в весенней безопасности - PullRequest
0 голосов
/ 18 октября 2019

Мне нужно сделать POST-запрос к / user / auth с телом json 'username' и 'password' для получения аутентификации пользователя из конечной точки безопасности Spring.

У меня есть форма входа в систему thymeleaf. он отправляет 'username' и 'password' в мою конечную точку пользовательского фильтра аутентификации.

Конечная точка запускается, но объект, который она получает, является нулевым.

Я могу использовать почтальон дляотправьте тело json в конечную точку, и я смогу войти в систему с успехом, но при использовании формы тимили, отправляемый мною объект является нулевым.

Что-то, что я пробовал: использование конечной точки перед аутентификацией для перехвата запросаи обрабатывает объект тимелист в JSON. Я думаю, что мне не хватает того, как использовать RestTemplate, хотя.



    @PostMapping(value = "/preauth", produces = "application/json")
    @ResponseBody
    public UserDto preAuth(@ModelAttribute LoginRequestModel loginRequestModel) {
        log.info("username to test: {}", loginRequestModel.getUsername());
        log.info("password to test: {}", loginRequestModel.getPassword());
// ^^ these are coming back correct ^^


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("username", loginRequestModel.getUsername());
        jsonObject.put("password", loginRequestModel.getPassword());

jsonObject.toMap().forEach((s, o) -> System.out.println(s + " : " + o));

// ^^ this also comes back correct ^^
// dont understand how to get this JSONObject inserted into the Rest Template

        RestTemplate restTemplate = new RestTemplate(jsonObject);

        restTemplate.exchange("http://localhost:8080/user/auth", loginRequestModel, LoginRequestModel.class);

        return userInfo;

    }
<form action="#" method="POST" th:action="@{/user/auth/preauth}" th:object="${loginRequestModel}">
    <p>Username: <input th:field="*{username}" type="text"/></p>
    <p>Password: <input th:field="*{password}" type="text"/></p>
    <p><input type="submit" value="Submit"/> <input type="reset" value="Reset"/></p>
public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        log.info("attempting to authenticate user");
        try {
            log.info("trying to map object");
            LoginRequestModel creds = new ObjectMapper()
                    .readValue(request.getInputStream(), LoginRequestModel.class);


            return getAuthenticationManager().authenticate(
                    new UsernamePasswordAuthenticationToken(
                            creds.getUsername(),
                            creds.getPassword(),
                            new ArrayList<>()
                    )
            );

        } catch (IOException e) {

            throw new RuntimeException(e);
        }

    }

по любой причине, request.getInputStream () возвращается как ноль, когда я пытаюсь вызвать его непосредственно из формы тимили в браузере.

[http-nio-8080-exec-3] DEBUG o.s.s.w.FilterChainProxy - /user/auth?username=admin&password=admin at position 5 of 12 in additional filter chain; firing Filter: 'AuthenticationFilter' 
[http-nio-8080-exec-3] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/user/auth'; against '/user/auth' 
[http-nio-8080-exec-3] DEBUG t.j.w.j.a.s.AuthenticationFilter - Request is to process authentication 
[http-nio-8080-exec-3] INFO  t.j.w.j.a.s.AuthenticationFilter - attempting to authenticate user 
[http-nio-8080-exec-3] INFO  t.j.w.j.a.s.AuthenticationFilter - trying to map object 
[http-nio-8080-exec-3] INFO  t.j.w.j.a.s.AuthenticationFilter - the exception was caught! 
[http-nio-8080-exec-3] INFO  t.j.w.j.a.s.AuthenticationFilter - the headers:: 
[http-nio-8080-exec-3] INFO  t.j.w.j.a.s.AuthenticationFilter - null 
[http-nio-8080-exec-3] INFO  t.j.w.j.a.s.AuthenticationFilter - null 
[http-nio-8080-exec-3] DEBUG o.s.s.w.h.w.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@46b257b6 
[http-nio-8080-exec-3] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 
[http-nio-8080-exec-3] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed 
[http-nio-8080-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
 at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 1, column: 0]
    at tech.jdevmin.web.jdevminweb.app.security.AuthenticationFilter.attemptAuthentication(AuthenticationFilter.java:72)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
 at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 1, column: 0]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4146)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3071)
    at tech.jdevmin.web.jdevminweb.app.security.AuthenticationFilter.attemptAuthentication(AuthenticationFilter.java:49)
    ... 51 common frames omitted

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Я исправил это! просто нужно было отправить объект thymeleaf конечной точке preauth и использовать HttpServletRequest для request.login () с именем пользователя и паролем непосредственно из html. не требуется сопоставление с JSON.

 @PostMapping(value = "/preauth", produces = "application/json")
    public String preAuth(@ModelAttribute LoginRequestModel loginRequestModel, HttpServletRequest request) throws IOException, ServletException {

        request.login(loginRequestModel.getUsername(),loginRequestModel.getPassword());

        return "index";

    }
0 голосов
/ 18 октября 2019

Я думаю, вы должны получить userName и password, как показано ниже, когда вы используете UsernamePasswordAuthenticationToken

 @Override
 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException {
    // TODO Auto-generated method stub
    request.getSession().setMaxInactiveInterval(sessionTimeout);

    CustomUsernamePasswordAuthenticationToken authRequest = getAuthRequest(request);
    _log.info("");
    setDetails(request, authRequest);

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

    private CustomUsernamePasswordAuthenticationToken getAuthRequest(HttpServletRequest request) {
         String username = obtainUsername(request);
     String password = obtainPassword(request);
    _log.info("UserName IN Filter : "+username);
    _log.info("UserName IN Filter : "+password);

    return new CustomUsernamePasswordAuthenticationToken(username, password);
}
...