7

我的应用程序使用 Spring Security,我的客户需要:

  • 用户注册后可以自动登录。
  • 管理员可以在不知道密码的情况下以任何用户身份登录。

所以我需要弄清楚如何在不知道密码的情况下自动以任何用户身份登录。

如何使用 Spring Security 实现这一点?

4

3 回答 3

7

为了让它发挥作用,我必须:

配置对 UserDetailsS​​ervice (jdbcUserService) 的引用

<authentication-manager>
<authentication-provider>
<jdbc-user-service id="jdbcUserService" data-source-ref="dataSource"
  users-by-username-query="select username,password, enabled from users where username=?" 
  authorities-by-username-query="select u.username, ur.authority from users u, user_roles ur where u.user_id = ur.user_id and u.username =?  " 
/>
</authentication-provider>
</authentication-manager>

在我的控制器中自动连接我的 userDetailsManager:

@Autowired
@Qualifier("jdbcUserService")  // <-- this references the bean id
public UserDetailsManager userDetailsManager;

在同一个控制器中,像这样对我的用户进行身份验证:

@RequestMapping("/automatic/login/test")
public @ResponseBody String automaticLoginTest(HttpServletRequest request) 
{
    String username = "anyUserName@YourSite.com";

    Boolean result = authenticateUserAndInitializeSessionByUsername(username, userDetailsManager, request);

    return result.toString();
}

public boolean authenticateUserAndInitializeSessionByUsername(String username, UserDetailsManager userDetailsManager, HttpServletRequest request)
{
    boolean result = true;

    try
    {
        // generate session if one doesn't exist
        request.getSession();

        // Authenticate the user
        UserDetails user = userDetailsManager.loadUserByUsername(username);
        Authentication auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(auth);
    }
    catch (Exception e)
    {
      System.out.println(e.getMessage());

      result = false;
    }

    return result;
}

请注意,可以在此处找到为您的应用程序使用 Spring Security 的一个很好的前兆。

于 2012-08-21T14:39:38.220 回答
1

对于第二个问题

管理员可以在不知道密码的情况下以任何用户身份登录。

您应该使用 spring 中的切换用户功能。javadoc文章

于 2012-08-21T15:03:13.733 回答
1

这是控制器中上述问题的答案 :

@RequestMapping(value = "/registerHere", method = RequestMethod.POST)
    public ModelAndView registerUser(@ModelAttribute("user") Users user, BindingResult result,
            HttpServletRequest request, HttpServletResponse response) {
        System.out.println("register 3");

        ModelAndView mv = new ModelAndView("/home");
        mv.addObject("homePagee", "true");

        String uname = user.getUsername();

        if (userDAO.getUserByName(uname) == null) {

            String passwordFromForm = user.getPassword();
            userDAO.saveOrUpdate(user);

            try {
                authenticateUserAndSetSession(user, passwordFromForm, request);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


        }

        System.out.println("register 4");

        log.debug("Ending of the method registerUser");
        return mv;
    }

控制器中的上述方法进一步定义为:

`private void authenticateUserAndSetSession(Users user, String passwor`dFromForm, HttpServletRequest request){

        String username = user.getUsername();
        System.out.println("username:  " + username + " password: " + passwordFromForm);                        

        UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, passwordFromForm, userDetails.getAuthorities());
        request.getSession();

        System.out.println("Line Authentication 1");

        usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetails(request));

        System.out.println("Line Authentication 2");

        Authentication authenticatedUser = authenticationManager.authenticate(usernamePasswordAuthenticationToken);

        System.out.println("Line Authentication 3");


        if (usernamePasswordAuthenticationToken.isAuthenticated()) {
            SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
            System.out.println("Line Authentication 4");

        }

     request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());// creates context for that session.

        System.out.println("Line Authentication 5");

        session.setAttribute("username", user.getUsername());

        System.out.println("Line Authentication 6");

        session.setAttribute("authorities", usernamePasswordAuthenticationToken.getAuthorities());

        System.out.println("username:  " + user.getUsername() + "password: " + user.getPassword()+"authorities: "+ usernamePasswordAuthenticationToken.getAuthorities());

        user = userDAO.validate(user.getUsername(), user.getPassword());
        log.debug("You are successfully register");

    }

其他答案不建议将其放入 try/catch 中,因此人们没有意识到为什么逻辑在代码运行时不起作用……而且控制台上没有任何错误或异常。因此,如果您不将其放入 try catch 中,您将不会得到错误凭据的异常。

于 2017-03-16T18:59:06.397 回答