java 如何在不知道密码的情况下使用 Spring Security 以用户身份自动登录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12057326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to automatically login as a user using Spring Security without knowing their password?
提问by Brad Parks
My application uses Spring Security, and my client requires:
我的应用程序使用 Spring Security,我的客户需要:
- users to be able to automatically login after signup.
- an admin to login as any user without knowing their password.
- 用户可以在注册后自动登录。
- 管理员在不知道密码的情况下以任何用户身份登录。
So I need to figure out how to login as any user automatically without knowing their password.
所以我需要弄清楚如何在不知道密码的情况下自动以任何用户身份登录。
How can this be accomplished using Spring Security?
如何使用 Spring Security 实现这一点?
采纳答案by Brad Parks
To get this to work, I had to:
为了让它发挥作用,我必须:
Configure a reference to the UserDetailsService (jdbcUserService)
配置对 UserDetailsService (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>
Autowire my userDetailsManager in my controller:
在我的控制器中自动装配我的 userDetailsManager:
@Autowired
@Qualifier("jdbcUserService") // <-- this references the bean id
public UserDetailsManager userDetailsManager;
In the same controller, authenticate my user like so:
在同一个控制器中,像这样验证我的用户:
@RequestMapping("/automatic/login/test")
public @ResponseBody String automaticLoginTest(HttpServletRequest request)
{
String username = "[email protected]";
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;
}
Note that a good precursor to just using spring security for your app can be found here.
请注意,可以在此处找到为您的应用程序仅使用 Spring Security 的良好前身。
回答by Jigar Parekh
回答by Yogesh Devgun
This is answer to above question In Controller:
这是对控制器中上述问题的回答 :
@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;
}
Further above method in controller is defined as:
控制器中的上述方法进一步定义为:
`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");
}
Other answers didnt suggest to put it in try/catch so one does not realize why logic is not working as code runs...and nothing is there neither error or exception on console. So if you wont put it in try catch you wont get exception of bad credentials.
其他答案并没有建议将它放在 try/catch 中,所以人们没有意识到为什么在代码运行时逻辑不起作用......控制台上没有任何错误或异常。所以如果你不把它放在 try catch 中,你就不会得到坏凭据的例外。