SpringSecurity - 自定义登录的一种思路

背景:支持其他登录方案例如证书登录

放行/login,自定义登录验证方式。

一、模板

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login")
                .permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("javaboy").password("{noop}123").roles("admin").build());
        provider.setUserDetailsService(manager);
        return new ProviderManager(provider);
    }
}

1、首先在登录放行中,添加 /login 接口,这是我即将自定义的第二个登录接口。
2、提供一个 AuthenticationManager 实例。创建 AuthenticationManager 实例时,还需要提供一个 DaoAuthenticationProvider,大家知道,用户密码的校验工作在这个类里边完成,并为 DaoAuthenticationProvider 配置一个 UserDetailsService 实例,该实体提供了用户数据源。

接下来提供一个登录接口:

@RestController
public class LoginController {
    @Autowired
    AuthenticationManager authenticationManager;
    @PostMapping("/login2")
    public String login2(String username, String password, HttpServletRequest req) {
        try {
            Authentication token = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
            SecurityContextHolder.getContext().setAuthentication(token);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "failed";
    }
}

  在登录接口中,传入用户名密码等参数,然后将用户名密码等参数封装成一个 UsernamePasswordAuthenticationToken 对象,最后调用 AuthenticationManager#authenticate 方法进行验证,验证成功后会返回一个认证后的 Authentication 对象,再手动把该 Authentication 对象存入 SecurityContextHolder 中。

二、自定义流程登录

通过自定义provider、自定义token 实现自定义的登录验证机制,这样比较灵活,两个都可以拓展。

1、注册自定义provider

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
	SM2AuthenticationProvider sm2AuthenticationProvider = new SM2AuthenticationProvider();
	sm2AuthenticationProvider.setUserDetailsService(userDetailsService);
	auth.authenticationProvider(sm2AuthenticationProvider);
}

2、provider 自定义 ,实现 implements AuthenticationProvider 接口

重写 supports、authenticate 方法,自定义的逻辑代码写在 authenticate 方法中,该方法最后返回一个认证通过的自定义的token

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
	SM2AuthenticationToken sm2AuthenticationToken = (SM2AuthenticationToken) authentication;
	UserDetails user = userDetailsService.loadUserByUsername((String) sm2AuthenticationToken.getPrincipal());;
	LoginUser loginUser = (LoginUser) user;
	.....
	.....
	SM2AuthenticationToken result = new SM2AuthenticationToken(user,user.getPassword(), user.getAuthorities());
	return result;
}

@Override
public boolean supports(Class<?> aClass) {
	return SM2AuthenticationToken.class.isAssignableFrom(aClass);
}

3、token自定义:继承extends AbstractAuthenticationToken ,可以根据需要拓展属性

4、实现验证

@Resource
private AuthenticationManager authenticationManager;

Authentication authentication = authenticationManager.authenticate(new SM2AuthenticationToken(username, password));

这样就完成验证流程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值