优化授权码模式

This commit is contained in:
zhuyijun 2022-10-15 21:21:22 +08:00
parent ed9885bf85
commit b2ee0701e1
8 changed files with 49 additions and 35 deletions

View File

@ -73,9 +73,12 @@ public class AuthFilter implements GlobalFilter {
if (isWhileList(path)) {
return chain.filter(exchange);
}
if (token == null || StringUtils.isEmpty(token) || !token.startsWith(HttpHeaderConstant.AUTHORIZATION_TYPE)) {
if (token == null || StringUtils.isEmpty(token)) {
return getErrorMono(response, HttpCode.UNAUTHORIZED, "无访问权限");
}
if (!token.toLowerCase().startsWith(HttpHeaderConstant.BEARER_TYPE.toLowerCase())) {
return getErrorMono(response, HttpCode.UNAUTHORIZED, "令牌格式有误");
}
if (isExpired(token)) {
log.info("token过期");
return getErrorMono(response, HttpCode.UNAUTHORIZED, "token失效");
@ -103,7 +106,7 @@ public class AuthFilter implements GlobalFilter {
* @date 2021/11/15 19:17
*/
private boolean isExpired(String token) {
String jwt = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE, "").trim();
String jwt = token.substring(HttpHeaderConstant.BEARER_TYPE.length()).trim();
try {
JwtParsers jwtParsers = new JwtParsers(true);
if (rsaKeyProperties.getEnable()) {

View File

@ -7,8 +7,6 @@ import org.springframework.security.oauth2.common.exceptions.InvalidGrantExcepti
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;
/**
* @author zhuyijun
@ -23,8 +21,7 @@ public class OauthAuthorizationCodeServices implements AuthorizationCodeServices
/**
* 生成随机字符的类
*/
private RandomValueStringGenerator generator = new RandomValueStringGenerator(10);
private RedisTokenStoreSerializationStrategy serializationStrategy = new JdkSerializationStrategy();
private RandomValueStringGenerator generator = new RandomValueStringGenerator(16);
/**
* @description 生成授权码的方法
@ -47,7 +44,9 @@ public class OauthAuthorizationCodeServices implements AuthorizationCodeServices
@SneakyThrows
@Override
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
return redisTemplateHandler.<String, OAuth2Authentication>hGet(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
OAuth2Authentication oAuth2Authentication = redisTemplateHandler.<String, OAuth2Authentication>hGet(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
redisTemplateHandler.hDelete(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
return oAuth2Authentication;
}

View File

@ -11,14 +11,16 @@ public class AuthorizationCodeDto {
@ApiModelProperty(value = "作用范围", dataType = "String", example = "all")
private String scope;
@ApiModelProperty(value = "回调地址", dataType = "String", example = "all")
private String redirectUrl;
private String redirect_uri;
@ApiModelProperty(value = "客户端id", dataType = "String", example = "all")
private String clientId;
private String client_id;
@ApiModelProperty(value = "客户端密码", dataType = "String", example = "all")
private String clientSecret;
@ApiModelProperty(value = "返回类型 code token", dataType = "String", example = "all")
private String responseType;
private String client_secret;
@ApiModelProperty(value = "响应体类型 code token", dataType = "String", example = "code token")
private String response_type;
@ApiModelProperty(value = "", dataType = "String", example = "")
private String state;
private Boolean isApproved;
@ApiModelProperty(value = "允许或拒绝 true 或false", dataType = "String", example = "true")
private String user_oauth_approval;
}

View File

@ -101,7 +101,7 @@ public class AuthServiceImpl implements AuthService {
@Override
public String getAuthorizationCode(AuthorizationCodeDto authorizationCodeDto) {
String responseType = authorizationCodeDto.getResponseType();
String responseType = authorizationCodeDto.getResponse_type();
if (!StringUtils.hasLength(responseType)) {
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "responseType不能为空");
}
@ -109,23 +109,34 @@ public class AuthServiceImpl implements AuthService {
if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
}
ClientDetails clientDetail = this.clientDetails.loadClientByClientId(authorizationCodeDto.getClientId());
ClientDetails clientDetail = this.clientDetails.loadClientByClientId(authorizationCodeDto.getClient_id());
if (clientDetail == null) {
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "无此客户端");
}
// if (!passwordEncoder.matches(clientDetail.getClientSecret(), authorizationCodeDto.getClientSecret())) {
// throw new AuthRuntimeException(HttpCode.UNAUTHORIZED, "客户端" + authorizationCodeDto.getClientId() + "认证失败");
// }
Map<String, String> parameters = new HashMap<>();
parameters.put(OAuth2Utils.CLIENT_ID, authorizationCodeDto.getClientId());
parameters.put("client_secret", authorizationCodeDto.getClientSecret());
parameters.put(OAuth2Utils.REDIRECT_URI, authorizationCodeDto.getRedirectUrl());
if (!passwordEncoder.matches(authorizationCodeDto.getClient_secret(), clientDetail.getClientSecret())) {
throw new AuthRuntimeException(HttpCode.UNAUTHORIZED, "客户端" + authorizationCodeDto.getClient_id() + "认证失败");
}
Map<String, String> parameters = new HashMap<>(16);
parameters.put(OAuth2Utils.CLIENT_ID, authorizationCodeDto.getClient_id());
parameters.put("client_secret", authorizationCodeDto.getClient_secret());
if (StringUtils.hasLength(authorizationCodeDto.getRedirect_uri())) {
parameters.put(OAuth2Utils.REDIRECT_URI, authorizationCodeDto.getRedirect_uri());
} else {
Set<String> registeredRedirectUri = clientDetail.getRegisteredRedirectUri();
if (CollectionUtils.isEmpty(registeredRedirectUri)) {
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "redirect_uri回调地址不能为空");
}
parameters.put(OAuth2Utils.REDIRECT_URI, registeredRedirectUri.toArray()[0].toString());
}
parameters.put(OAuth2Utils.RESPONSE_TYPE, "code");
parameters.put(OAuth2Utils.SCOPE, authorizationCodeDto.getScope());
parameters.put(OAuth2Utils.STATE, authorizationCodeDto.getState());
parameters.put(OAuth2Utils.USER_OAUTH_APPROVAL, authorizationCodeDto.getUser_oauth_approval());
AuthorizationRequest authorizationRequest = createAuthorizationRequest(parameters, clientDetail);
if (!authorizationCodeDto.getIsApproved()) {
String flag = parameters.get(OAuth2Utils.USER_OAUTH_APPROVAL);
boolean isApproved = "true".equalsIgnoreCase(flag);
authorizationRequest.setApproved(isApproved);
if (!isApproved) {
return getUnsuccessfulRedirect(authorizationRequest,
new UserDeniedAuthorizationException("User denied access"), false);
}

View File

@ -49,18 +49,18 @@ public class LoginServiceImpl implements LoginService {
@Override
public OAuth2AccessTokenVo login(UserLoginDto userLoginDto) {
Map<String, String> parameters = BeanUtils.map(userLoginDto, Map.class);
parameters.put("username",userLoginDto.getUserIdentification());
parameters.put("password",userLoginDto.getPwdOrVerifyCode());
parameters.put("username", userLoginDto.getUserIdentification());
parameters.put("password", userLoginDto.getPwdOrVerifyCode());
parameters.put("grant_type", "password");
ClientDetails authenticatedClient = clientDetails.loadClientByClientId(clientId);
if (authenticatedClient == null) {
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, "客户端获取token失败");
}
try{
try {
TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
OAuth2AccessToken token = tokenGranter.grant(tokenRequest.getGrantType(), tokenRequest);
return OAuth2AccessTokenVo.TransferToken(token);
}catch (Exception e){
} catch (Exception e) {
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
@ -71,7 +71,7 @@ public class LoginServiceImpl implements LoginService {
if (StringUtils.isEmpty(token)) {
return;
}
token = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE, "").trim();
token = token.substring(HttpHeaderConstant.BEARER_TYPE.length()).trim();
OAuth2AccessToken oAuth2AccessToken = new DefaultOAuth2AccessToken(token);
tokenStore.removeAccessToken(oAuth2AccessToken);
}

View File

@ -2,7 +2,7 @@ package cn.zyjblogs.starter.common.entity.constant;
public class HttpHeaderConstant {
public static final String AUTHORIZATION = "Authorization";
public static final String AUTHORIZATION_TYPE = "Bearer";
public static final String BEARER_TYPE = "Bearer";
public static final String LANGUAGE = "istorm-language";
public static final String REQUEST_FROM_GATEWAY_KEY = "request-from-istorm-gateway";
public static final String REQUEST_FROM_GATEWAY_VALUE = "yes";

View File

@ -35,8 +35,8 @@ public class OauthFeignInterceptorAutoConfiguration {
* @date 2022/03/12
*/
private String tokenCompletion(String token) {
if (token.indexOf(HttpHeaderConstant.AUTHORIZATION_TYPE) != 0) {
token = HttpHeaderConstant.AUTHORIZATION_TYPE + " " + token;
if (token.indexOf(HttpHeaderConstant.BEARER_TYPE) != 0) {
token = HttpHeaderConstant.BEARER_TYPE + " " + token;
}
return token;
}

View File

@ -83,11 +83,10 @@ public class RabbitMqAutoConfiguration {
* @date 2021/11/12 9:17
*/
private void setContext(String authorization) {
String type = HttpHeaderConstant.AUTHORIZATION_TYPE;
if (!authorization.startsWith(type)) {
if (!authorization.toLowerCase().startsWith(HttpHeaderConstant.BEARER_TYPE.toLowerCase())) {
return;
}
String token = authorization.replace(HttpHeaderConstant.AUTHORIZATION_TYPE, "").trim();
String token = authorization.substring(HttpHeaderConstant.BEARER_TYPE.length()).trim();
JwtParsers jwtParsers = new JwtParsers(false);
try {