标签:密码登录 ted 用户访问 manager 判断 rgba OAuth2 tip ror
近期遇到一个问题,在spring oauth2.0默认的密码登录校验中,只能访问单个数据库表,但针对不同的表用户,需要访问不同的表,所以需要传一个新参去判断用户访问不同的表来校验账号密码
本文主要是是讨论oauth2.0支持多表用户登录
我使用的Spring Boot为2.2.5.RELEAS,SpringCloud为Hoxton.SR2
对于多个表用户,需要传递不同的参数来区分是访问哪个表,所以在请求参数中增加了loginType来区分不同的用户
创建 MultipleLoginAuthenticationSecurityConfig,自义定配置 extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>
复写config配置
@Override public void configure(HttpSecurity http) { // 自定义过滤期 MultipleLoginAuthenticationFilter multipleLoginAuthenticationFilter = new MultipleLoginAuthenticationFilter(); multipleLoginAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); // 自定义的登录成功跳转Handler multipleLoginAuthenticationFilter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler); // 自定义登录失败跳转Handler multipleLoginAuthenticationFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler); // 自定义鉴权提供者 MultipleLoginAuthenticationProvider multipleLoginAuthenticationProvider = new MultipleLoginAuthenticationProvider(); // 数据访问 multipleLoginAuthenticationProvider.setUserDetailsService(userDetailsService); // 密码校验 multipleLoginAuthenticationProvider.setPasswordEncoder(passwordEncoder); // 配置鉴权提供者,以及过滤器,并将过滤的执行顺序放在 UsernamePasswordAuthenticationFilter http.authenticationProvider(multipleLoginAuthenticationProvider) .addFilterBefore(multipleLoginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); }
UsernamePasswordAuthenticationFilter是spring security提供的表单登录Filter
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException( "Authentication method not supported: " + request.getMethod()); } //获取登录的账号密码 String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); // 查询所有配置的provider并用登录用户名获取账号密码做校验 return this.getAuthenticationManager().authenticate(authRequest); }
所以我们需要新创建一个新的provider来替代再带的密码校验方式
@Slf4j public class MultipleLoginAuthenticationProvider implements AuthenticationProvider { private MyUserDetailsService userDetailsService; private PasswordEncoder passwordEncoder; private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword"; private volatile String userNotFoundEncodedPassword; public MultipleLoginAuthenticationProvider() { passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); } @Override @SuppressWarnings("unchecked") public Authentication authenticate(Authentication authentication) throws AuthenticationException { MultipleLoginAuthenticationToken authenticationToken = (MultipleLoginAuthenticationToken) authentication; Map<String, String> details = (Map<String, String>) authenticationToken.getDetails(); // 自定义添加 String loginType = details.get("loginType"); // 自定义添加userType参数 UserDetails user = this.getUserDetailsService().loadUserByLoginType(authentication.getName(), loginType); if (user == null) { throw new InternalAuthenticationServiceException( "用户信息为空"); } if (!"APP".equals(loginType)) { // app登录不校验密码 // 获取当前输入的密码 String presentedPassword = authentication.getCredentials().toString(); if (!passwordEncoder.matches(presentedPassword, user.getPassword())) { log.error("用户名或密码错误,用户名:" + authentication.getName()); throw new BadCredentialsException("用户名或密码错误"); } } if (details.containsKey("password")) { details.put("password", null); } MultipleLoginAuthenticationToken authenticationResult = new MultipleLoginAuthenticationToken(user, user.getAuthorities()); authenticationResult.setDetails(authenticationToken.getDetails()); return authenticationResult; } @Override public boolean supports(Class<?> authentication) { return MultipleLoginAuthenticationToken.class.isAssignableFrom(authentication); } public PasswordEncoder getPasswordEncoder() { return passwordEncoder; } public String getUserNotFoundEncodedPassword() { return userNotFoundEncodedPassword; } public void setUserNotFoundEncodedPassword(String userNotFoundEncodedPassword) { this.userNotFoundEncodedPassword = userNotFoundEncodedPassword; } public void setPasswordEncoder(PasswordEncoder passwordEncoder) { Assert.notNull(passwordEncoder, "passwordEncoder cannot be null"); this.passwordEncoder = passwordEncoder; this.userNotFoundEncodedPassword = null; } public MyUserDetailsService getUserDetailsService() { return userDetailsService; } public void setUserDetailsService(MyUserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } }
标签:密码登录 ted 用户访问 manager 判断 rgba OAuth2 tip ror
原文地址:https://www.cnblogs.com/yuitstyle/p/14738952.html