赞
踩
通过查看UsernamePasswordAuthenticationFilter
获取用户名和密码的实现方法可以看到,默认只能获取form表单提供的数据,无法获得请求体中的数据。所以,要想获得请求体中的数据,需要自定义过滤器。
这里有两种方式获得用户名和密码
obtainPassword
和obtainUsername
attemptAuthentication
这个方法我们可以发现,用户名和密码是在这个方法里面获得并且使用的,因此我们可以直接重写这个方法。@Slf4j public class UserAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Autowired private AuthenticationManager authenticationManager; @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException { try { Employee employee = new ObjectMapper().readValue(req.getInputStream(), Employee.class); return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(employee.getUsername(), employee.getPassword())); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } } }
public interface IEmployeeService extends IService<Employee>,UserDetailsService {
}
EmployeeServiceImpl实现类
这里只需要实现loadUserByUsername方法,验证用户是否存在、是否被禁用
@Service public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService{ @Autowired EmployeeMapper employeeMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println(employeeMapper); System.out.println(username); QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.eq("username",username); Employee employee = employeeMapper.selectOne(wrapper); UserDetails userDetail = User.withUsername(username).password(employee.getPassword()).roles(username).build(); return userDetail; } }
通过继承DaoAuthenticationProvider,可以自定义用户密码验证并查看异常信息。
若不实现该类,抛出的异常信息会都变成Bad credentials
@Component public class UserLoginAuthenticationProvider extends DaoAuthenticationProvider { @Autowired private UserDetailsServiceImpl detailsService; @Autowired private PasswordEncoder encoder; /** * 找到容器中的detailsService,并执行setUserDetailsService方法,完成赋值 * * 必须要给UserDetailsService赋值,否则会出现UnsatisfiedDependencyException */ @Autowired private void setDetailsService() { setUserDetailsService(detailsService); } @Override protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { String presentedPassword = authentication.getCredentials().toString(); if (!encoder.matches(presentedPassword, userDetails.getPassword())) { throw new BadCredentialsException(messages.getMessage("badCredentials", "用户密码错误")); } } }
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired IEmployeeService employeeService; //注入AuthenticationManager,可能存在同名bean, //配置文件中设置allow-bean-definition-overriding: true @Bean @Override protected AuthenticationManager authenticationManager() throws Exception { return super.authenticationManager(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //使用DetailsService进行数据校验 auth.userDetailsService(employeeService).passwordEncoder(passwordEncoder()); //使用自定义的Provider,进行数据校验 // auth.authenticationProvider(loginAuthenticationProvider); } @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } //重要,将UserAuthenticationFilter添加到容器 @Bean public UserAuthenticationFilter userAuthenticationFilter() throws Exception { UserAuthenticationFilter filter = new UserAuthenticationFilter(); //设置验证成功后的回调 filter.setAuthenticationSuccessHandler((request,response,authentication)->{ //响应成功状态码必须为200 response.setStatus(200); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding("utf-8"); //将数据以json的形式返回给前台 response.getWriter().print(JSON.toJSONString(Result.success(null))); }); //设置验证失败后的回调 filter.setAuthenticationFailureHandler((request, response, exception) ->{ response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding("utf-8"); //将数据以json的形式返回给前台 response.getWriter().print(JSON.toJSONString(Result.error("登录失败"))); }); //设置用户发起登陆请求时的url filter.setFilterProcessesUrl("/employee/login"); filter.setAuthenticationManager(authenticationManager()); return filter; } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() //屏蔽跨站请求 .authorizeRequests() .anyRequest().permitAll() .and() .formLogin() // .loginPage("employee/login") .loginProcessingUrl("/employee/login") .successForwardUrl("/success"); http.cors(); // 开启跨域 //添加自定义的过滤器 http.addFilterAt(userAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } }
本文参考于:http://t.zoukankan.com/xlwq-p-13411575.html
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。