Tom*_*mas 10 spring spring-security spring-boot
我有一个Spring Boot应用程序,WebSecurityConfigurerAdapter配置如下 -
http.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers("/user/*", "/habbit/*").authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.permitAll()
.usernameParameter("email")
.passwordParameter("pass")
.successHandler(authenticationSuccessHandler)
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout()
.logoutUrl("/logout")
.invalidateHttpSession(true);
Run Code Online (Sandbox Code Playgroud)
我可以添加类似我自己的控制器,在成功验证后,返回一个自定义对象,其中包含有关经过身份验证的用户的一些详细信息吗?
更新: 为了清晰起见,我使用角度应用程序作为客户端.目前,我需要从客户端向服务器发出2个请求:1.POST请求/登录URL进行身份验证.2. GET请求以检索经过身份验证的用户数据.
我的目标是让第一个请求返回给我用户信息,所以我不必提出2dn请求.目前,第一个请求仅对用户进行身份验证,在服务器上创建会话并发送回没有数据的"200 OK"状态响应.我希望它返回有关登录用户数据的成功响应.
回答:
正确的答案在评论中,所以我将在这里写:我需要从我的successHandler重定向到我的控制器,然后控制器返回当前登录的用户信息(在我的情况下控制器在url'/ user/me':
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
clearAuthenticationAttributes(request);
getRedirectStrategy().sendRedirect(request, response, "/user/me");
}
Run Code Online (Sandbox Code Playgroud)
Ken*_*kov 10
如果我理解你的问题,我可以建议下一步.
首先,您必须实现包含用户信息的类.该类必须继承自org.springframework.security.core.userdetails.User:
public class CustomUserDetails extends User {
public CustomUserDetails(String username, String password,
Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
}
//for example lets add some person data
private String firstName;
private String lastName;
//getters and setters
}
Run Code Online (Sandbox Code Playgroud)
下一步,您已创建自己的接口实现org.springframework.security.core.userdetails.UserDetailsService:
@Service
public class CustomUserDetailService implements UserDetailsService{
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException{
if(StringUtils.isEmpty(userName))
throw new UsernameNotFoundException("User name is empty");
//if you don't use authority based security, just add empty set
Set<GrantedAuthority> authorities = new HashSet<>();
CustomUserDetails userDetails = new CustomUserDetails(userName, "", authorities);
//here you can load user's data from DB or from
//any other source and do:
//userDetails.setFirstName(firstName);
//userDetails.setLastName(lastName);
return userDetails;
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,此类只有一种方法,您可以在其中加载和设置自定义用户详细信息.注意,我用@Service注释标记了这个类.但您可以在Java-config或XML上下文中注册它.
现在,要在成功验证后访问您的用户数据,您可以使用下一种方法,当Spring将自动在控制器的方法中传递principal:
@Controller
public class MyController{
@RequestMapping("/mapping")
public String myMethod(Principal principal, ModelMap model){
CustomUserDetails userDetails = (CustomUserDetails)principal;
model.addAttribute("firstName", userDetails.getFirstName());
model.addAttribute("lastName", userDetails.getLastName());
}
}
Run Code Online (Sandbox Code Playgroud)
或另一种方式:
@Controller
public class MyController{
@RequestMapping("/mapping")
public String myMethod(ModelMap model){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
CustomUserDetails userDetails = (CustomUserDetails)auth.getPrincipal();
model.addAttribute("firstName", userDetails.getFirstName());
model.addAttribute("lastName", userDetails.getLastName());
}
}
Run Code Online (Sandbox Code Playgroud)
此方法可以在其他地方使用,其中Spring不会自动传递主体.
要在成功验证后转到特定地址,您可以使用SimpleUrlAuthenticationSuccessHandler.只需在您的配置中创建它:
@Bean
public SavedRequestAwareAuthenticationSuccessHandler successHandler() {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("/succeslogin");
return successHandler;
}
Run Code Online (Sandbox Code Playgroud)
并在您的配置中使用它:
http.formLogin()
.loginProcessingUrl("/login")
.permitAll()
.usernameParameter("email")
.passwordParameter("pass")
.successHandler(successHandler())
Run Code Online (Sandbox Code Playgroud)
之后你可以创建控制器,它将从speciafied url发送响应:
@Controller
@RequestMapping("/sucesslogin")
public class SuccessLoginController{
@RequestMapping(method = RequestMethod.POST)
public String index(ModelMap model, Principal principal){
//here you can return view with response
}
}
Run Code Online (Sandbox Code Playgroud)
原因是,您不仅可以返回视图,还可以返回JSON响应(使用@ResponseBody注释)或其他内容,这取决于您的前端.希望这会有所帮助.
在接受的答案中,您需要两次调用才能获取所需的数据。像这样在自定义 AjaxAuthenticationSuccessHandler 中简单地在登录后返回数据。
@Bean
public AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() {
return new AjaxAuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.getWriter().write(new ObjectMapper().writeValueAsString(new UserAuthenticationResponse(authentication.getName(), 123l)));
response.setStatus(200);
}
};
}
Run Code Online (Sandbox Code Playgroud)
并注册成功处理程序:
http.successHandler(ajaxAuthenticationSuccessHandler())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12800 次 |
| 最近记录: |