java - Spring 安全 : Accessing secured resources using cookie returned at login

标签 java spring cookies spring-security resttemplate

我正在开发一个 Java 桌面应用程序,经过一番搜索后,我能够使用 RestTemplate 对用户进行身份验证。现在的情况是我在桌面端有cookie字符串(代码如下)。现在我想做的是做两件重要的事情,获取哪个用户使用该 cookie 登录并访问(GET、POST、DELETE)用 @Secured 或 @PreAuthorize 注释标记的安全资源。

这是我的身份验证代码:

   @Override
    public void initialize(URL location, ResourceBundle resources) {
        submitButton.setOnAction(event -> {
           if(!(usernameField.getText().isEmpty() && passwordField.getText().isEmpty())){
               try {
                   RestTemplate rest = new RestTemplate();
                   String jsessionid = rest.execute("http://localhost:8080/j_spring_security_check", HttpMethod.POST,
                           new RequestCallback() {
                               @Override
                               public void doWithRequest(ClientHttpRequest request) throws IOException {
                                   request.getBody().write(("j_username=" + usernameField.getText() + "&j_password=" + passwordField.getText()).getBytes());
                               }
                           }, new ResponseExtractor<String>() {
                               @Override
                               public String extractData(ClientHttpResponse response) throws IOException {
                                   List<String> cookies = response.getHeaders().get("Cookie");

                                   // assuming only one cookie with jsessionid as the only value
                                   if (cookies == null) {
                                       cookies = response.getHeaders().get("Set-Cookie");
                                   }

                                   String cookie = cookies.get(cookies.size() - 1);
                                   System.out.println("Cookie is "+cookie);
                                   int start = cookie.indexOf('=');
                                   int end = cookie.indexOf(';');

                                   return cookie.substring(start + 1, end);
                               }
                           });

              //   rest.put("http://localhost:8080/rest/program.json;jsessionid=" + jsessionid, new DAO("REST Test").asJSON());

               } catch (AuthenticationException e) {
                   System.out.println("AuthenticationException");
               }
           } else {
               System.out.println("Fields are empty");
           }
        });
    }

程序的输出是:

DEBUG: org.springframework.web.client.RestTemplate - Created POST request for "http://localhost:8080/j_spring_security_check"
DEBUG: org.springframework.web.client.RestTemplate - POST request for "http://localhost:8080/j_spring_security_check" resulted in 302 (Found)
Cookie is JSESSIONID=903B2924CCC84421931D52A4F0AA3C7E; Path=/; HttpOnly

如果我在服务器端,我只需调用以下方法即可获取当前经过身份验证的用户:

 @Override
    public Person getCurrentlyAuthenticatedUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return null;
        } else {
            return personDAO.findPersonByUsername(authentication.getName());
        }
    }

如何在基于桌面的java应用程序上获取当前的身份验证用户,以便我可以使用下面的方法并在桌面java应用程序上进行身份验证。 :

Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        Authentication authentication = new UsernamePasswordAuthenticationToken(person1, null, authorities);
        SecurityContextHolder.getContext().setAuthentication(authentication);

这样,我也可以在桌面 Java 应用程序中使用 @Secured 注释。多谢。

更新

因此,在服务器端,我创建了一个方法,为我提供登录用户。正如答案中所建议的,我可以使用相同的休息模板,但我想将 cookie 存储在用户本地数据库中,而不是在用户单击此处和那里时传递 Resttemplates 对象。

服务器端方法:

@Secured("ROLE_USER")
@RequestMapping(value = "/rest/getloggedinuser", method = RequestMethod.GET)
public
@ResponseBody
ResponseEntity<RestPerson> getLoggedInRestUser() {
    Person person = this.personService.getCurrentlyAuthenticatedUser();
    RestPerson restPerson = new RestPerson();
    restPerson.setFirstname(person.getFirstName());
    restPerson.setUsername(person.getUsername());
    restPerson.setPassword("PROTECTED");
    return new ResponseEntity<RestPerson>(restPerson, HttpStatus.OK);
}

现在,接下来,我尝试使用相同的 RestTemplate 来检查此方法是否适用于下面的代码,但我真的很想知道如何仅使用 cookie 来做到这一点:

 HttpHeaders requestHeaders = new HttpHeaders();
                                   requestHeaders.add("Cookie", cookie);
                                   HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
                                   ResponseEntity rssResponse = rest.exchange(
                                           "/rest/getloggedinuser",
                                           HttpMethod.GET,
                                           requestEntity,
                                           Person.class);
                                   String rssResponseBody = (String)rssResponse.getBody();
                                   System.out.println("Response body is ");

有没有办法将ResponseBody中的Object转换为Person对象???

最佳答案

  1. 如果您想获取一些存储在服务器端的用户信息,您应该在您的服务器上创建一个新服务,例如“getUserInformation”,它将提供此类信息。
  2. 您不应该手动提取 cookie,只需重用相同的 RestTemplate,它在内部存储 cookie(特别是在底层 HttpClient 中)。这就是您获取安全资源的方式。

更新:

您不需要传递 RestTemplate,只需将其设为单例并在任何地方使用它即可。

并且 rssResponse.getBody(); 应该返回一个 Person 对象,而不是 String。

关于java - Spring 安全 : Accessing secured resources using cookie returned at login,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31161174/

相关文章:

PHP:记住我和安全?

php - 未生成 Javascript cookie

php - 使用登录的 Laravel 子域重定向

java - 字符串替换在 for 循环中不起作用 - Java

spring - 使用 mockito 为 spring-boot 应用程序模拟 Qualified bean

java - java中方法的继承和重写

java - Spring security 同一子网下的多个IP

java - spring中的认证机制

java - 冒泡排序法+里面的排列法

java - 从 csv 文件行创建 Java 对象的开销是多少