码迷,mamicode.com
首页 > 编程语言 > 详细

spring ouath2 多表用户登录

时间:2021-05-24 00:36:35      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:密码登录   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;
    }
}

 

spring ouath2 多表用户登录

标签:密码登录   ted   用户访问   manager   判断   rgba   OAuth2   tip   ror   

原文地址:https://www.cnblogs.com/yuitstyle/p/14738952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!