Как пройти аутентификацию и перенаправить на внешнее приложение для единого входа? - PullRequest
0 голосов
/ 16 июня 2019

Я пытаюсь реализовать простую функцию единого входа в моем весеннем веб-приложении. Сценарий:

  1. У меня есть основное приложение Application1 и дополнительное приложение2. Оба имеют свои собственные механизмы входа в систему (используя формы входа в систему Spring-Security).

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

Вот что я попробовал:

  1. Я создал API в Application2, который принимает электронную почту в качестве входных данных, проверяет ее, создает сеанс пользователя и возвращает строку URL.

    @RequestMapping(path = "/sso/login", consumes = "application/json", method = RequestMethod.POST)
    public String login(@RequestBody SSOparams params, HttpServletRequest req, ModelMap model) {
    
    // 1. validates email from params
    
    // 2. creates Authentication object:
    UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(username, password);
    Authentication auth = authManager.authenticate(authReq);
    SecurityContext sc = SecurityContextHolder.getContext();
    sc.setAuthentication(auth);
    HttpSession session = req.getSession(true);
    session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, sc);
    
    // 3. returns a url string:
    return "/user/dashboard";
    }
    
  2. Пользователь входит в приложение 1.

  3. На домашней странице Application1, когда пользователь щелкает ссылку Application2, вызывается метод контроллера Application1.

  4. Метод контроллера Application1 вызывает API входа Application2 с параметром электронной почты и, наконец, перенаправляет на URL-адрес, возвращенный из API.

    Метод контроллера Application1:

    @RequestMapping(value = "/callapplication2", method = RequestMethod.POST)
    public String callapplication2(ModelMap model,HttpSession session) {
    String output = "";
    String redirectionUrl = "";
    try {
        // 1. calling application2's login API
        URL url = new URL("http://localhost:8080/application2/api/sso/login");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
    
        String input = "{\"uniqueemail\":\"abc@gmail.com\"}";
    
        OutputStream os = conn.getOutputStream();
        os.write(input.getBytes());
        os.flush();
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        while ((output = br.readLine()) != null) {  
            redirectionUrl = redirectionUrl + output;
        }
        conn.disconnect();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    
     // 2. returns a url
    return "redirect:http://localhost:8080/application2" + redirectionUrl ;
    }
    

Все вышеперечисленное работает нормально. Но когда я войду в Application1 и нажму на ссылку application2, я ожидаю, что приложение должно перенаправить http://localhost:8080/application2/user/dashboard без заполнения учетных данных.

Но вместо этого открывается страница входа в Application2. Я вижу в сетевой консоли Chrome, что /user/dashboard вызывается, но поскольку страница защищена, я перенаправлен на страницу входа application2.

Означает ли это, что аутентификация, которую я создал с помощью API, не используется. Чего мне не хватает?

1 Ответ

0 голосов
/ 16 июня 2019
        Best approach is to set filter in web.xml and put it in top of the list.

        Whenever your application will get any request it will first go to the filter and there you will check that session is present or not if its null then simply redirect to your sso login page else respective landing page.

        Now in your case,
          Solution i can see

          1) Put filter into app2 web.xml

          2) Now when you redirect from app1 to app2 (Pass one parameter anything like username, email whatever)

          3) Store it into the session.

          4) Whenever any request will come to app2 you will first verify session from filter, If username found that means user not need to login again else redirect to sso login page.

          Thats standars steps (I belive)
          5) Having a peek into your implementation.Specifically you have to add one more step into app filter. When you are redirecting from app1 for te first time with http://localhost:8080/application2/user/dashboard ( You will pass one parameter along with this url as explained above). 
          This let you to check 2 condition into your filter. Either request should have valid parameter or username should be into session. If any condition stated true you can let redirect request to further else you have to redirect to login page. 

          Hope this will help to resolve your issue.
...