思路:在登录成功后的AuthenticationSuccessHandler获取token,传给前端。
@Component("fuiouAuthenticationSuccessHandler")
@Slf4j
public class FuiouAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private AuthorizationServerTokenServices authorizationServerTokenServices;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//authentication 封装了认证信息
// 1、获取请求中的clientId和clientSecret
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Basic ")) {
throw new UnapprovedClientAuthenticationException("请求头中无client信息");
}
String[] tokens = extractAndDecodeHeader(header, request);
String clientId=tokens[0];
String clientSecret=tokens[1];
// 2、获取clientDetails
ClientDetails clientDetails=clientDetailsService.loadClientByClientId(clientId);
if(clientDetails==null) {
throw new UnapprovedClientAuthenticationException("clientId对应的配置信息不存在"+clientId);
}else if(!StringUtils.equals(clientSecret, clientDetails.getClientSecret())) {
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 oAuth2AccessToken=authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(oAuth2AccessToken));
}
private String[] extractAndDecodeHeader(String header, HttpServletRequest request)
throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
}
catch (IllegalArgumentException e) {
throw new BadCredentialsException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, "UTF-8");
int delim = token.indexOf(":");
if (delim == -1) {
throw new BadCredentialsException("Invalid basic authentication token");
}
return new String[] { token.substring(0, delim), token.substring(delim + 1) };
}
}
@Configuration
@EnableResourceServer
public class FuiouResourceServerConfig extends ResourceServerConfigurerAdapter{
@Autowired
private AuthenticationSuccessHandler fuiouAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler fuiouAuthenticationFailureHandler;
@Autowired
private SecurityProperties securityProperties;
@Autowired
private SpringSocialConfigurer fuiouSocialSecurityConfig;
@Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
@Override
public void configure(HttpSecurity http) throws Exception {
// ValidateCodeFilter filter=new ValidateCodeFilter();
// filter.setAuthenticationFailureHandler(fuiouAuthenticationFailureHandler);
// filter.setSecurityProperties(securityProperties);
// filter.afterPropertiesSet();
SmsCodeFilter smsCodefilter=new SmsCodeFilter();
smsCodefilter.setAuthenticationFailureHandler(fuiouAuthenticationFailureHandler);
smsCodefilter.setSecurityProperties(securityProperties);
smsCodefilter.afterPropertiesSet();
http
.apply(fuiouSocialSecurityConfig)
.and()
.addFilterBefore(smsCodefilter, UsernamePasswordAuthenticationFilter.class)
//.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class)
.formLogin()
.loginPage("/authentication/requrie")//登录页面
.loginProcessingUrl("/authentication/form")
.successHandler(fuiouAuthenticationSuccessHandler)
.failureHandler(fuiouAuthenticationFailureHandler)
.and()
.authorizeRequests()//请求授权
.antMatchers("/authentication/requrie",
securityProperties.getBrowser().getLoginPage(),
"/code/*",securityProperties.getBrowser().getSiginUpUrl(),
"/user/regist","/session/invalid","/index.html",
"/fuiou-logOut.html","/signOut")
.permitAll()//该url不需要身份认证
.anyRequest() //任何请求
.authenticated()//身份认证
.and()
.csrf().disable()//关闭csrf防护
.apply(smsCodeAuthenticationSecurityConfig)
;
}
}
这样登录后就能得到token