-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
393 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
...java/org/funcode/portal/server/common/core/security/domain/WechatAuthenticationToken.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* Copyright 2024 李冲. All rights reserved. | ||
* | ||
*/ | ||
|
||
package org.funcode.portal.server.common.core.security.domain; | ||
|
||
import lombok.Getter; | ||
import org.springframework.security.authentication.AbstractAuthenticationToken; | ||
import org.springframework.security.core.GrantedAuthority; | ||
|
||
import java.util.Collection; | ||
|
||
/** | ||
* 微信登录认证Token | ||
* | ||
* @author 李冲 | ||
* @see <a href="https://lichong.work">李冲博客</a> | ||
* @since 0.0.1 | ||
*/ | ||
@Getter | ||
public class WechatAuthenticationToken extends AbstractAuthenticationToken { | ||
private final String openId; | ||
private final Object principal; | ||
|
||
/** | ||
* 未认证的Token | ||
* | ||
* @param openId openId | ||
*/ | ||
public WechatAuthenticationToken(String openId) { | ||
super(null); | ||
this.openId = openId; | ||
this.principal = openId; | ||
setAuthenticated(false); | ||
} | ||
|
||
/** | ||
* 已认证的token | ||
* | ||
* @param openId openId | ||
* @param authorities 权限 | ||
*/ | ||
public WechatAuthenticationToken(String openId, Object principal, Collection<? extends GrantedAuthority> authorities) { | ||
super(authorities); | ||
this.openId = openId; | ||
this.principal = principal; | ||
setAuthenticated(true); | ||
} | ||
|
||
/** | ||
* 未认证的Token | ||
* | ||
* @param openId openId | ||
*/ | ||
public static WechatAuthenticationToken unauthenticated(String openId) { | ||
return new WechatAuthenticationToken(openId); | ||
} | ||
|
||
/** | ||
* 已认证的token | ||
* | ||
* @param openId openId | ||
* @param authorities 权限 | ||
*/ | ||
public static WechatAuthenticationToken authenticated(String openId, Object principal, Collection<? extends GrantedAuthority> authorities) { | ||
return new WechatAuthenticationToken(openId, principal, authorities); | ||
} | ||
|
||
@Override | ||
public Object getCredentials() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public Object getPrincipal() { | ||
return this.principal; | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
...ava/org/funcode/portal/server/common/core/security/filter/WechatAuthenticationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright 2024 李冲. All rights reserved. | ||
* | ||
*/ | ||
|
||
package org.funcode.portal.server.common.core.security.filter; | ||
|
||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import org.funcode.portal.server.common.core.security.domain.WechatAuthenticationToken; | ||
import org.funcode.portal.server.common.core.security.handler.WechatAuthenticationFailureHandler; | ||
import org.funcode.portal.server.common.core.security.handler.WechatAuthenticationSuccessHandler; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.AuthenticationServiceException; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; | ||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | ||
import org.springframework.util.ObjectUtils; | ||
|
||
/** | ||
* 微信登录认证 | ||
* | ||
* @author 李冲 | ||
* @see <a href="https://lichong.work">李冲博客</a> | ||
* @since 0.0.1 | ||
*/ | ||
public class WechatAuthenticationFilter extends AbstractAuthenticationProcessingFilter { | ||
/** | ||
* 微信登录路径 | ||
*/ | ||
public static final String WECHAT_LOGIN_PATH = "/wechat/login"; | ||
/** | ||
* 允许的请求方法 | ||
*/ | ||
public static final String METHOD = "POST"; | ||
/** | ||
* 参数名称 | ||
*/ | ||
public static final String PARAM_KEY = "code"; | ||
/** | ||
* 路径匹配 | ||
*/ | ||
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher(WECHAT_LOGIN_PATH, METHOD); | ||
|
||
|
||
public WechatAuthenticationFilter(AuthenticationManager authenticationManager, | ||
WechatAuthenticationSuccessHandler wechatAuthenticationSuccessHandler, | ||
WechatAuthenticationFailureHandler wechatAuthenticationFailureHandler) { | ||
super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager); | ||
setAuthenticationFailureHandler(wechatAuthenticationFailureHandler); | ||
setAuthenticationSuccessHandler(wechatAuthenticationSuccessHandler); | ||
} | ||
|
||
/** | ||
* 从请求中取出code参数,向微信服务器发送请求,如果成功获取到openID,则创建一个未认证的 WechatAuthenticationToken , 并将其提交给 AuthenticationManager | ||
*/ | ||
@Override | ||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { | ||
if (!METHOD.equals(request.getMethod())) { | ||
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); | ||
} | ||
final String code = request.getParameter(PARAM_KEY); | ||
if (ObjectUtils.isEmpty(code)) { | ||
throw new AuthenticationServiceException("code 不允许为空"); | ||
} | ||
// 创建一个未认证的token,放入code | ||
final WechatAuthenticationToken token = WechatAuthenticationToken.unauthenticated(code); | ||
// 设置details | ||
token.setDetails(this.authenticationDetailsSource.buildDetails(request)); | ||
// 将token提交给 AuthenticationManager | ||
return this.getAuthenticationManager().authenticate(token); | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...uncode/portal/server/common/core/security/handler/WechatAuthenticationFailureHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2024 李冲. All rights reserved. | ||
* | ||
*/ | ||
|
||
package org.funcode.portal.server.common.core.security.handler; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.funcode.portal.server.common.core.base.http.response.ResponseResult; | ||
import org.funcode.portal.server.common.core.base.http.response.ResponseStatusEnum; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.web.authentication.AuthenticationFailureHandler; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* @author 李冲 | ||
* @see <a href="https://lichong.work">李冲博客</a> | ||
* @since 0.0.1 | ||
*/ | ||
@Slf4j | ||
@Component | ||
@RequiredArgsConstructor | ||
public class WechatAuthenticationFailureHandler implements AuthenticationFailureHandler { | ||
|
||
@Override | ||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { | ||
response.setContentType(MediaType.APPLICATION_JSON_VALUE); | ||
response.setStatus(HttpStatus.UNAUTHORIZED.value()); | ||
ObjectMapper mapper = new ObjectMapper(); | ||
response.getWriter().write(mapper.writeValueAsString(ResponseResult.fail(exception.getLocalizedMessage(), ResponseStatusEnum.HTTP_STATUS_401))); | ||
} | ||
} |
Oops, something went wrong.