1. 自定義token,繼承 AbstractAuthenticationToken
目的:主要用於包裝區別過濾條件。第2步用到。
public class WxLoginAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 510L;
private final Object principal;
private Object credentials;
public WxLoginAuthenticationToken(Object principal, Object credentials) {
super((Collection)null);
this.principal = principal;
this.credentials = credentials;
this.setAuthenticated(false);
}
public WxLoginAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
public Object getCredentials() {
return this.credentials;
}
public Object getPrincipal() {
return this.principal;
}
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
} else {
super.setAuthenticated(false);
}
}
public void eraseCredentials() {
super.eraseCredentials();
this.credentials = null;
}
}
2. 自定義攔截類Filter,繼承 AbstractAuthenticationProcessingFilter
目的:對前端傳輸過來的數據進行包裝,
public class WxLoginFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
private String usernameParameter = "username";
private String passwordParameter = "password";
private boolean postOnly = true;
public WxLoginFilter() {
super(new AntPathRequestMatcher("/wx/login", "POST"));
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} else {
HashMap hashMap = JSONObject.parseObject(ReadAsChars(request), HashMap.class);
String username = (String) hashMap.get("username");
String password = (String) hashMap.get("password");
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
// 該處對第一步的token進行包裝
WxLoginAuthenticationToken authRequest = new WxLoginAuthenticationToken(username, password);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
}
public static String ReadAsChars(HttpServletRequest request)
{
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try
{
br = request.getReader();
String str;
while ((str = br.readLine()) != null)
{
sb.append(str);
}
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (null != br)
{
try
{
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return sb.toString();
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(this.passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(this.usernameParameter);
}
protected void setDetails(HttpServletRequest request, WxLoginAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
}
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
}
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
}
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return this.usernameParameter;
}
public final String getPasswordParameter() {
return this.passwordParameter;
}
}
3. 實現登錄驗證邏輯
@Slf4j
@Component
public class WxLoginProvider implements AuthenticationProvider {
@Autowired
ISysUserService userService;
@Autowired
private SysPermissionService permissionService;
@Resource
private AuthenticationManager authenticationManager;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
log.info("第三方微信登錄");
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
//該處僅供參考,不做登錄邏輯處理。登錄成功後,返回對應的值,返回null則登錄失敗
return null;
}
@Override
public boolean supports(Class<?> aClass) {
return WxLoginAuthenticationToken.class.isAssignableFrom(aClass);
}
}
4. security配置
由於項目原因,僅貼上部分代碼:
至此,完成自定義(多方式)登錄驗證。多個登錄方式,可添加多個處理.
參考文檔:
https://blog.csdn.net/qq_36521507/article/details/103365805
https://blog.csdn.net/qq_36521507/article/details/103370070