spring oauth2 实现用户名密码登录、手机号验证码登录返回token
文章目录
介绍
spring oauth2提供了授权码,密码等模式。登录成功之后返回token。但在app中,需要用户名和密码或者是手机号验证码登录成功之后也返回token。下面将对这两种模式登录成功之后返回token功能。
实现功能
用户名密码或者手机号验证码登录成功之后返回token。
用户名密码登录
步骤
接着上一章的源码继续写。
编写成功处理器
该处理器是用来处理登录成功之后,该怎么返回数据,如果网页请求,不处理。如果是app请求,则返回token。
/**
* @author lvhaibao
* @description 当用户登录成功之后做的处理
* @date 2019/1/8 0008 10:06
*/
@Component
@Slf4j
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private AuthorizationServerTokenServices authorizationServerTokenServices;
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
log.info("登录成功之后的处理");
String type = request.getHeader("Accept");
if(!type.contains("text/html")){
String clientId = "app";
String clientSecret = "app";
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
if (null == clientDetails) {
throw new UnapprovedClientAuthenticationException("clientId不存在" + clientId);
} else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
throw new UnapprovedClientAuthenticationException("clientSecret不匹配" + clientId);
}
TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom");
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(token));
}else {
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
配置成功处理器
配置成功处理器在ebSecurityConfig里面配置。
/**
* @author lvhaibao
* @description 浏览器配置
* @date 2018/12/25 0025 10:53
*/
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
@Autowired
private VcodeManager vcodeManager;
@Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
@Autowired
private SpringSocialConfigurer mySocialSecurityConfig;
@Autowired
private DataSource dataSource;
@Autowired
private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
// @Override
// @Bean
// public AuthenticationManager authenticationManagerBean() throws Exception {
// return super.authenticationManagerBean();
// }
/**
* 生成记得我的token
*
* @return
*/
@Bean
public PersistentTokenRepository persistentTokenRepository() {
//使用jdbc来存储
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
//设置数据源
tokenRepository.setDataSource(dataSource);
//当为true的时候就会自动创建表
//tokenRepository.setCreateTableOnStartup(true);
return tokenRepository;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SmsCodeFilter smsCodeFilter = new SmsCodeFilter(vcodeManager);
smsCodeFilter.setSecurityProperties(securityProperties);
smsCodeFilter.afterPropertiesSet();
http.addFilterBefore(smsCodeFilter, UsernamePasswordAuthenticationFilter.class)
//表单登录,loginPage为登录请求的url,loginProcessingUrl为表单登录处理的URL
.formLogin().loginPage(FromLoginConstant.LOGIN_PAGE).loginProcessingUrl(FromLoginConstant.LOGIN_PROCESSING_URL)
//登录成功之后的处理
.successHandler(myAuthenticationSuccessHandler)
//允许访问
.and().authorizeRequests().antMatchers(
FromLoginConstant.LOGIN_PROCESSING_URL,
FromLoginConstant.LOGIN_PAGE,
securityProperties.getOauthLogin().getOauthLogin(),
securityProperties.getOauthLogin().getOauthGrant(),
"/myLogout",
"/code/sms")
// "/oauth/**")
.permitAll().anyRequest().authenticated()
//禁用跨站伪造
.and().csrf().disable()
//短信验证码配置
.apply(smsCodeAuthenticationSecurityConfig)
//社交登录
.and().apply(mySocialSecurityConfig);
}
}
手机号验证码登录
步骤
重写SmsCodeAuthenticationSecurityConfig
在SmsCodeAuthenticationSecurityConfig里面再配置成功处理器
/**
* @author lvhaibao
* @description
* @date 2019/1/2 0002 10:39
*/
@Component
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
@Autowired
private MyUserDetailsServiceImpl myUserDetailsService;
@Autowired
private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
@Override
public void configure(HttpSecurity http) throws Exception {
SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();
//设置AuthenticationManager
smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
//设置成功失败处理器
smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler);
// smsCodeAuthenticationFilter.setAuthenticationFailureHandler(myAuthenticationSuccessHandler);
//设置provider
SmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();
smsCodeAuthenticationProvider.setMyUserDetailsService(myUserDetailsService);
http.authenticationProvider(smsCodeAuthenticationProvider)
.addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
测试
用户名密码登录
使用工具。post请求如下地址:http://127.0.0.1/authentication/form。
手机号验证码登录
先获取验证码多少。get请求如下地址:
然后post请求如下地址:http://www.pinzhi365.com/authentication/mobile
项目源码
https://gitee.com/lvhaibao/spring-lhbauth/tree/34a4e781abeb9f1115b7a2e53141e0fed2915757/