优化授权码模式
This commit is contained in:
parent
b2ee0701e1
commit
4b68d1bfeb
@ -59,7 +59,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
|
||||
.authorizeRequests()
|
||||
.antMatchers(String.join(",", whiteListProperties.getAllowPaths()))
|
||||
.permitAll()
|
||||
.antMatchers("/v*/user/login", "/v*/auth/refresh/token").permitAll()
|
||||
.antMatchers("/v*/user/login", "/v*/auth/refresh/token", "/v*/auth/authorize/code").permitAll()
|
||||
//以下请求必须认证通过
|
||||
.anyRequest()
|
||||
.authenticated().and()
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.zyjblogs.server.user.controller;
|
||||
|
||||
import cn.zyjblogs.server.user.dto.AuthCodeDto;
|
||||
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
|
||||
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
|
||||
import cn.zyjblogs.server.user.service.AuthService;
|
||||
@ -34,18 +35,24 @@ public class AuthController {
|
||||
return ResponseResult.success(authService.refreshToken(oAuth2AccessTokenDto));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "检测token", notes = "刷新token")
|
||||
@ApiOperation(value = "检测token", notes = "检测token")
|
||||
@PostMapping("/check/token")
|
||||
@ApiVersion(1)
|
||||
public ResponseObject<OAuth2AccessTokenVo> checkToken(@RequestBody @Validated OAuth2AccessTokenDto oAuth2AccessTokenDto) {
|
||||
return ResponseResult.success(authService.checkToken(oAuth2AccessTokenDto));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取授权码", notes = "刷新token")
|
||||
@ApiOperation(value = "获取授权码", notes = "获取授权码")
|
||||
@PostMapping("/authorize")
|
||||
@ApiVersion(1)
|
||||
public ResponseObject getAuthorizationCode(@RequestBody @Validated AuthorizationCodeDto authorizationCodeDto) {
|
||||
return ResponseResult.success(authService.getAuthorizationCode(authorizationCodeDto));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "通过授权码获取token", notes = "获取授权码")
|
||||
@PostMapping("/authorize/code")
|
||||
@ApiVersion(1)
|
||||
public ResponseObject<OAuth2AccessTokenVo> getTokenByAuthorizationCode(@RequestBody @Validated AuthCodeDto authCodeDto) {
|
||||
return ResponseResult.success(authService.getTokenByAuthorizationCode(authCodeDto));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.zyjblogs.server.user.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author zhuyijun
|
||||
*/
|
||||
@ApiModel(description = "接收授权码模式对象")
|
||||
@Data
|
||||
public class AuthCodeDto {
|
||||
@ApiModelProperty(value = "授权码", dataType = "String", example = "all")
|
||||
private String code;
|
||||
@ApiModelProperty(value = "客户端id", dataType = "String", example = "all")
|
||||
private String client_id;
|
||||
@ApiModelProperty(value = "客户端密码", dataType = "String", example = "all")
|
||||
private String client_secret;
|
||||
@ApiModelProperty(value = "回调地址", dataType = "String", example = "code token")
|
||||
private String redirect_url;
|
||||
}
|
@ -11,7 +11,7 @@ public class AuthorizationCodeDto {
|
||||
@ApiModelProperty(value = "作用范围", dataType = "String", example = "all")
|
||||
private String scope;
|
||||
@ApiModelProperty(value = "回调地址", dataType = "String", example = "all")
|
||||
private String redirect_uri;
|
||||
private String redirect_url;
|
||||
@ApiModelProperty(value = "客户端id", dataType = "String", example = "all")
|
||||
private String client_id;
|
||||
@ApiModelProperty(value = "客户端密码", dataType = "String", example = "all")
|
||||
@ -22,5 +22,4 @@ public class AuthorizationCodeDto {
|
||||
private String state;
|
||||
@ApiModelProperty(value = "允许或拒绝 true 或false", dataType = "String", example = "true")
|
||||
private String user_oauth_approval;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,204 @@
|
||||
package cn.zyjblogs.server.user.handler;
|
||||
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
|
||||
import org.springframework.security.oauth2.common.util.OAuth2Utils;
|
||||
import org.springframework.security.oauth2.provider.AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author zhuyijun
|
||||
*/
|
||||
public class OauthRquestHander {
|
||||
/**
|
||||
* 处理
|
||||
*
|
||||
* @param authorizationParameters
|
||||
* @param clientDetails
|
||||
* @return
|
||||
*/
|
||||
public static AuthorizationRequest createAuthorizationRequest(Map<String, String> authorizationParameters, ClientDetails clientDetails) {
|
||||
String clientId = authorizationParameters.get(OAuth2Utils.CLIENT_ID);
|
||||
String state = authorizationParameters.get(OAuth2Utils.STATE);
|
||||
String redirectUri = authorizationParameters.get(OAuth2Utils.REDIRECT_URI);
|
||||
Set<String> responseTypes = OAuth2Utils.parseParameterList(authorizationParameters
|
||||
.get(OAuth2Utils.RESPONSE_TYPE));
|
||||
Set<String> scopes = OAuth2Utils.parseParameterList(authorizationParameters.get(OAuth2Utils.SCOPE));
|
||||
if (CollectionUtils.isEmpty(scopes)) {
|
||||
scopes = clientDetails.getScope();
|
||||
}
|
||||
AuthorizationRequest request = new AuthorizationRequest(authorizationParameters,
|
||||
Collections.emptyMap(), clientId, scopes, null, null, false, state, redirectUri,
|
||||
responseTypes);
|
||||
request.setResourceIdsAndAuthoritiesFromClientDetails(clientDetails);
|
||||
return request;
|
||||
}
|
||||
|
||||
public static String appendAccessToken(AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) {
|
||||
|
||||
Map<String, Object> vars = new LinkedHashMap<String, Object>();
|
||||
Map<String, String> keys = new HashMap<String, String>();
|
||||
|
||||
if (accessToken == null) {
|
||||
throw new InvalidRequestException("An implicit grant could not be made");
|
||||
}
|
||||
|
||||
vars.put("access_token", accessToken.getValue());
|
||||
vars.put("refresh_token", accessToken.getRefreshToken());
|
||||
vars.put("token_type", accessToken.getTokenType());
|
||||
vars.put("expiration", accessToken.getExpiration());
|
||||
String state = authorizationRequest.getState();
|
||||
|
||||
if (state != null) {
|
||||
vars.put("state", state);
|
||||
}
|
||||
Date expiration = accessToken.getExpiration();
|
||||
if (expiration != null) {
|
||||
long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000;
|
||||
vars.put("expires_in", expires_in);
|
||||
}
|
||||
String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
|
||||
if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) {
|
||||
vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope()));
|
||||
}
|
||||
Map<String, Object> additionalInformation = accessToken.getAdditionalInformation();
|
||||
for (String key : additionalInformation.keySet()) {
|
||||
Object value = additionalInformation.get(key);
|
||||
if (value != null) {
|
||||
keys.put("extra_" + key, key);
|
||||
vars.put("extra_" + key, value);
|
||||
}
|
||||
}
|
||||
// Do not include the refresh token (even if there is one)
|
||||
return append(authorizationRequest.getRedirectUri(), vars, keys, true);
|
||||
}
|
||||
|
||||
private static String append(String base, Map<String, ?> query, Map<String, String> keys, boolean fragment) {
|
||||
|
||||
UriComponentsBuilder template = UriComponentsBuilder.newInstance();
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base);
|
||||
URI redirectUri;
|
||||
try {
|
||||
// assume it's encoded to start with (if it came in over the wire)
|
||||
redirectUri = builder.build(true).toUri();
|
||||
} catch (Exception e) {
|
||||
// ... but allow client registrations to contain hard-coded non-encoded values
|
||||
redirectUri = builder.build().toUri();
|
||||
builder = UriComponentsBuilder.fromUri(redirectUri);
|
||||
}
|
||||
template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost())
|
||||
.userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath());
|
||||
|
||||
if (fragment) {
|
||||
StringBuilder values = new StringBuilder();
|
||||
if (redirectUri.getFragment() != null) {
|
||||
String append = redirectUri.getFragment();
|
||||
values.append(append);
|
||||
}
|
||||
for (String key : query.keySet()) {
|
||||
if (values.length() > 0) {
|
||||
values.append("&");
|
||||
}
|
||||
String name = key;
|
||||
if (keys != null && keys.containsKey(key)) {
|
||||
name = keys.get(key);
|
||||
}
|
||||
values.append(name + "={" + key + "}");
|
||||
}
|
||||
if (values.length() > 0) {
|
||||
template.fragment(values.toString());
|
||||
}
|
||||
UriComponents encoded = template.build().expand(query).encode();
|
||||
builder.fragment(encoded.getFragment());
|
||||
} else {
|
||||
for (String key : query.keySet()) {
|
||||
String name = key;
|
||||
if (keys != null && keys.containsKey(key)) {
|
||||
name = keys.get(key);
|
||||
}
|
||||
template.queryParam(name, "{" + key + "}");
|
||||
}
|
||||
template.fragment(redirectUri.getFragment());
|
||||
UriComponents encoded = template.build().expand(query).encode();
|
||||
builder.query(encoded.getQuery());
|
||||
}
|
||||
|
||||
return builder.build().toUriString();
|
||||
}
|
||||
|
||||
private static String append(String base, Map<String, ?> query, boolean fragment) {
|
||||
return append(base, query, (Map) null, fragment);
|
||||
}
|
||||
|
||||
public static String getSuccessfulRedirect(AuthorizationRequest authorizationRequest, String authorizationCode) {
|
||||
if (authorizationCode == null) {
|
||||
throw new IllegalStateException("No authorization code found in the current request scope.");
|
||||
} else {
|
||||
Map<String, String> query = new LinkedHashMap();
|
||||
query.put("code", authorizationCode);
|
||||
String state = authorizationRequest.getState();
|
||||
if (state != null) {
|
||||
query.put("state", state);
|
||||
}
|
||||
|
||||
return append(authorizationRequest.getRedirectUri(), query, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUnsuccessfulRedirect(AuthorizationRequest authorizationRequest, OAuth2Exception failure, boolean fragment) {
|
||||
if (authorizationRequest != null && authorizationRequest.getRedirectUri() != null) {
|
||||
Map<String, String> query = new LinkedHashMap();
|
||||
query.put("error", failure.getOAuth2ErrorCode());
|
||||
query.put("error_description", failure.getMessage());
|
||||
if (authorizationRequest.getState() != null) {
|
||||
query.put("state", authorizationRequest.getState());
|
||||
}
|
||||
|
||||
if (failure.getAdditionalInformation() != null) {
|
||||
Iterator var5 = failure.getAdditionalInformation().entrySet().iterator();
|
||||
|
||||
while (var5.hasNext()) {
|
||||
Map.Entry<String, String> additionalInfo = (Map.Entry) var5.next();
|
||||
query.put(additionalInfo.getKey(), additionalInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return append(authorizationRequest.getRedirectUri(), query, fragment);
|
||||
} else {
|
||||
throw new UnapprovedClientAuthenticationException("Authorization failure, and no redirect URI.", failure);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUnsuccessfulRedirect(String redirectUri, OAuth2Exception failure, boolean fragment) {
|
||||
if (StringUtils.hasLength(redirectUri)) {
|
||||
Map<String, String> query = new LinkedHashMap();
|
||||
query.put("error", failure.getOAuth2ErrorCode());
|
||||
query.put("error_description", failure.getMessage());
|
||||
if (failure.getAdditionalInformation() != null) {
|
||||
Iterator var5 = failure.getAdditionalInformation().entrySet().iterator();
|
||||
while (var5.hasNext()) {
|
||||
Map.Entry<String, String> additionalInfo = (Map.Entry) var5.next();
|
||||
query.put(additionalInfo.getKey(), additionalInfo.getValue());
|
||||
}
|
||||
}
|
||||
return append(redirectUri, query, fragment);
|
||||
} else {
|
||||
throw new UnapprovedClientAuthenticationException("Authorization failure, and no redirect URI.", failure);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cn.zyjblogs.server.user.service;
|
||||
|
||||
import cn.zyjblogs.server.user.dto.AuthCodeDto;
|
||||
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
|
||||
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
|
||||
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
|
||||
@ -30,4 +31,12 @@ public interface AuthService {
|
||||
* @param authorizationCodeDto
|
||||
*/
|
||||
String getAuthorizationCode(AuthorizationCodeDto authorizationCodeDto);
|
||||
|
||||
/**
|
||||
* @param authCodeDto
|
||||
* @return
|
||||
* @author zhuyijun
|
||||
* @date 2022/10/15
|
||||
*/
|
||||
OAuth2AccessTokenVo getTokenByAuthorizationCode(AuthCodeDto authCodeDto);
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package cn.zyjblogs.server.user.service.impl;
|
||||
|
||||
import cn.zyjblogs.server.user.dto.AuthCodeDto;
|
||||
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
|
||||
import cn.zyjblogs.server.user.dto.AuthorizationDto;
|
||||
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
|
||||
import cn.zyjblogs.server.user.handler.OauthRquestHander;
|
||||
import cn.zyjblogs.server.user.po.OauthUserDetails;
|
||||
import cn.zyjblogs.server.user.service.AuthService;
|
||||
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
|
||||
@ -14,9 +16,7 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UnsupportedResponseTypeException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
|
||||
import org.springframework.security.oauth2.common.util.OAuth2Utils;
|
||||
@ -32,19 +32,12 @@ import org.springframework.security.oauth2.provider.TokenRequest;
|
||||
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
|
||||
import org.springframework.security.oauth2.provider.implicit.ImplicitTokenRequest;
|
||||
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -62,7 +55,7 @@ public class AuthServiceImpl implements AuthService {
|
||||
|
||||
public AuthServiceImpl(AuthorizationServerEndpointsConfiguration authorizationServerEndpointsConfiguration,
|
||||
ClientDetailsService clientDetails,
|
||||
TokenStore tokenStore, AuthorizationCodeServices authorizationCodeServices, PasswordEncoder passwordEncoder) {
|
||||
AuthorizationCodeServices authorizationCodeServices, PasswordEncoder passwordEncoder) {
|
||||
this.tokenGranter = authorizationServerEndpointsConfiguration.getEndpointsConfigurer().getTokenGranter();
|
||||
this.clientDetails = clientDetails;
|
||||
this.oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetails);
|
||||
@ -99,45 +92,51 @@ public class AuthServiceImpl implements AuthService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取授权码
|
||||
*
|
||||
* @param authorizationCodeDto
|
||||
* @return
|
||||
* @author zhuyijun
|
||||
* @date 2022/10/15
|
||||
*/
|
||||
@Override
|
||||
public String getAuthorizationCode(AuthorizationCodeDto authorizationCodeDto) {
|
||||
String responseType = authorizationCodeDto.getResponse_type();
|
||||
String redirect_url = authorizationCodeDto.getRedirect_url();
|
||||
if (!StringUtils.hasLength(responseType)) {
|
||||
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "responseType不能为空");
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(redirect_url, new OAuth2Exception("responseType不能为空"), false);
|
||||
}
|
||||
Set<String> responseTypes = Set.of(responseType.split(","));
|
||||
if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
|
||||
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(redirect_url, new OAuth2Exception("Unsupported response types: " + responseTypes), false);
|
||||
}
|
||||
ClientDetails clientDetail = this.clientDetails.loadClientByClientId(authorizationCodeDto.getClient_id());
|
||||
if (clientDetail == null) {
|
||||
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "无此客户端");
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(redirect_url, new OAuth2Exception("无此客户端"), false);
|
||||
}
|
||||
if (!passwordEncoder.matches(authorizationCodeDto.getClient_secret(), clientDetail.getClientSecret())) {
|
||||
throw new AuthRuntimeException(HttpCode.UNAUTHORIZED, "客户端" + authorizationCodeDto.getClient_id() + "认证失败");
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(redirect_url, new OAuth2Exception("客户端" + authorizationCodeDto.getClient_id() + "认证失败"), false);
|
||||
}
|
||||
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.REDIRECT_URI, redirect_url);
|
||||
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);
|
||||
Set<String> registeredRedirectUri = clientDetail.getRegisteredRedirectUri();
|
||||
if (!redirect_url.equals(registeredRedirectUri.toArray()[0].toString())) {
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(authorizationRequest,
|
||||
new UserDeniedAuthorizationException("回调地址不一致"), false);
|
||||
}
|
||||
String flag = parameters.get(OAuth2Utils.USER_OAUTH_APPROVAL);
|
||||
boolean isApproved = "true".equalsIgnoreCase(flag);
|
||||
authorizationRequest.setApproved(isApproved);
|
||||
if (!isApproved) {
|
||||
return getUnsuccessfulRedirect(authorizationRequest,
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(authorizationRequest,
|
||||
new UserDeniedAuthorizationException("User denied access"), false);
|
||||
}
|
||||
if (responseTypes.contains("token")) {
|
||||
@ -152,10 +151,34 @@ public class AuthServiceImpl implements AuthService {
|
||||
oauthUserDetails.setTenantId(BaseContext.getTenantId());
|
||||
authorizationDto.setPrincipal(oauthUserDetails);
|
||||
authorizationDto.setAuthenticated(true);
|
||||
return getSuccessfulRedirect(authorizationRequest,
|
||||
return OauthRquestHander.getSuccessfulRedirect(authorizationRequest,
|
||||
generateCode(authorizationRequest, authorizationDto));
|
||||
} catch (OAuth2Exception e) {
|
||||
return getUnsuccessfulRedirect(authorizationRequest, e, false);
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(authorizationRequest, e, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenVo getTokenByAuthorizationCode(AuthCodeDto authCodeDto) {
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("redirect_uri", authCodeDto.getRedirect_url());
|
||||
parameters.put("grant_type", "authorization_code");
|
||||
parameters.put("client_id", authCodeDto.getClient_id());
|
||||
parameters.put("code", authCodeDto.getCode());
|
||||
parameters.put("client_secret", authCodeDto.getClient_secret());
|
||||
ClientDetails clientDetail = clientDetails.loadClientByClientId(authCodeDto.getClient_id());
|
||||
if (clientDetail == null) {
|
||||
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "该客户端不存在");
|
||||
}
|
||||
if (!passwordEncoder.matches(authCodeDto.getClient_secret(), clientDetail.getClientSecret())) {
|
||||
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "该客户端认证失败");
|
||||
}
|
||||
try {
|
||||
TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, clientDetail);
|
||||
OAuth2AccessToken token = tokenGranter.grant(tokenRequest.getGrantType(), tokenRequest);
|
||||
return OAuth2AccessTokenVo.TransferToken(token);
|
||||
} catch (Exception e) {
|
||||
throw new AuthRuntimeException(HttpCode.BAD_REQUEST, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,44 +207,6 @@ public class AuthServiceImpl implements AuthService {
|
||||
|
||||
}
|
||||
|
||||
private String appendAccessToken(AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) {
|
||||
|
||||
Map<String, Object> vars = new LinkedHashMap<String, Object>();
|
||||
Map<String, String> keys = new HashMap<String, String>();
|
||||
|
||||
if (accessToken == null) {
|
||||
throw new InvalidRequestException("An implicit grant could not be made");
|
||||
}
|
||||
|
||||
vars.put("access_token", accessToken.getValue());
|
||||
vars.put("refresh_token", accessToken.getRefreshToken());
|
||||
vars.put("token_type", accessToken.getTokenType());
|
||||
vars.put("expiration", accessToken.getExpiration());
|
||||
String state = authorizationRequest.getState();
|
||||
|
||||
if (state != null) {
|
||||
vars.put("state", state);
|
||||
}
|
||||
Date expiration = accessToken.getExpiration();
|
||||
if (expiration != null) {
|
||||
long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000;
|
||||
vars.put("expires_in", expires_in);
|
||||
}
|
||||
String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
|
||||
if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) {
|
||||
vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope()));
|
||||
}
|
||||
Map<String, Object> additionalInformation = accessToken.getAdditionalInformation();
|
||||
for (String key : additionalInformation.keySet()) {
|
||||
Object value = additionalInformation.get(key);
|
||||
if (value != null) {
|
||||
keys.put("extra_" + key, key);
|
||||
vars.put("extra_" + key, value);
|
||||
}
|
||||
}
|
||||
// Do not include the refresh token (even if there is one)
|
||||
return append(authorizationRequest.getRedirectUri(), vars, keys, true);
|
||||
}
|
||||
|
||||
private String getImplicitGrantResponse(AuthorizationRequest authorizationRequest) {
|
||||
try {
|
||||
@ -231,9 +216,9 @@ public class AuthServiceImpl implements AuthService {
|
||||
if (accessToken == null) {
|
||||
throw new UnsupportedResponseTypeException("Unsupported response type: token");
|
||||
}
|
||||
return appendAccessToken(authorizationRequest, accessToken);
|
||||
return OauthRquestHander.appendAccessToken(authorizationRequest, accessToken);
|
||||
} catch (OAuth2Exception e) {
|
||||
return getUnsuccessfulRedirect(authorizationRequest, e, true);
|
||||
return OauthRquestHander.getUnsuccessfulRedirect(authorizationRequest, e, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,99 +247,4 @@ public class AuthServiceImpl implements AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
private String append(String base, Map<String, ?> query, Map<String, String> keys, boolean fragment) {
|
||||
|
||||
UriComponentsBuilder template = UriComponentsBuilder.newInstance();
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base);
|
||||
URI redirectUri;
|
||||
try {
|
||||
// assume it's encoded to start with (if it came in over the wire)
|
||||
redirectUri = builder.build(true).toUri();
|
||||
} catch (Exception e) {
|
||||
// ... but allow client registrations to contain hard-coded non-encoded values
|
||||
redirectUri = builder.build().toUri();
|
||||
builder = UriComponentsBuilder.fromUri(redirectUri);
|
||||
}
|
||||
template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost())
|
||||
.userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath());
|
||||
|
||||
if (fragment) {
|
||||
StringBuilder values = new StringBuilder();
|
||||
if (redirectUri.getFragment() != null) {
|
||||
String append = redirectUri.getFragment();
|
||||
values.append(append);
|
||||
}
|
||||
for (String key : query.keySet()) {
|
||||
if (values.length() > 0) {
|
||||
values.append("&");
|
||||
}
|
||||
String name = key;
|
||||
if (keys != null && keys.containsKey(key)) {
|
||||
name = keys.get(key);
|
||||
}
|
||||
values.append(name + "={" + key + "}");
|
||||
}
|
||||
if (values.length() > 0) {
|
||||
template.fragment(values.toString());
|
||||
}
|
||||
UriComponents encoded = template.build().expand(query).encode();
|
||||
builder.fragment(encoded.getFragment());
|
||||
} else {
|
||||
for (String key : query.keySet()) {
|
||||
String name = key;
|
||||
if (keys != null && keys.containsKey(key)) {
|
||||
name = keys.get(key);
|
||||
}
|
||||
template.queryParam(name, "{" + key + "}");
|
||||
}
|
||||
template.fragment(redirectUri.getFragment());
|
||||
UriComponents encoded = template.build().expand(query).encode();
|
||||
builder.query(encoded.getQuery());
|
||||
}
|
||||
|
||||
return builder.build().toUriString();
|
||||
}
|
||||
|
||||
private String append(String base, Map<String, ?> query, boolean fragment) {
|
||||
return this.append(base, query, (Map) null, fragment);
|
||||
}
|
||||
|
||||
private String getSuccessfulRedirect(AuthorizationRequest authorizationRequest, String authorizationCode) {
|
||||
if (authorizationCode == null) {
|
||||
throw new IllegalStateException("No authorization code found in the current request scope.");
|
||||
} else {
|
||||
Map<String, String> query = new LinkedHashMap();
|
||||
query.put("code", authorizationCode);
|
||||
String state = authorizationRequest.getState();
|
||||
if (state != null) {
|
||||
query.put("state", state);
|
||||
}
|
||||
|
||||
return this.append(authorizationRequest.getRedirectUri(), query, false);
|
||||
}
|
||||
}
|
||||
|
||||
private String getUnsuccessfulRedirect(AuthorizationRequest authorizationRequest, OAuth2Exception failure, boolean fragment) {
|
||||
if (authorizationRequest != null && authorizationRequest.getRedirectUri() != null) {
|
||||
Map<String, String> query = new LinkedHashMap();
|
||||
query.put("error", failure.getOAuth2ErrorCode());
|
||||
query.put("error_description", failure.getMessage());
|
||||
if (authorizationRequest.getState() != null) {
|
||||
query.put("state", authorizationRequest.getState());
|
||||
}
|
||||
|
||||
if (failure.getAdditionalInformation() != null) {
|
||||
Iterator var5 = failure.getAdditionalInformation().entrySet().iterator();
|
||||
|
||||
while (var5.hasNext()) {
|
||||
Map.Entry<String, String> additionalInfo = (Map.Entry) var5.next();
|
||||
query.put(additionalInfo.getKey(), additionalInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return this.append(authorizationRequest.getRedirectUri(), query, fragment);
|
||||
} else {
|
||||
throw new UnapprovedClientAuthenticationException("Authorization failure, and no redirect URI.", failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,3 +105,5 @@ security:
|
||||
client:
|
||||
client-id: ${spring.application.name}
|
||||
client-secret: secret
|
||||
resource:
|
||||
id: ${spring.application.name}
|
@ -105,5 +105,5 @@ security:
|
||||
client-id: ${spring.application.name}
|
||||
client-secret: secret
|
||||
resource:
|
||||
id: resourceId
|
||||
id: ${spring.application.name}
|
||||
|
||||
|
@ -24,7 +24,7 @@ import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
@RequiredArgsConstructor
|
||||
@RefreshScope
|
||||
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
|
||||
@Value("${spring.application.name}")
|
||||
@Value("${security.oauth2.resource.id}")
|
||||
private String resourceId;
|
||||
private final TokenStore tokenStore;
|
||||
private final WhiteListProperties whiteListProperties;
|
||||
|
Loading…
Reference in New Issue
Block a user